2012-11-07 12 views
5

Ho letto i documenti ocaml ma non riesco a capire la parte che spiega come { x with ... } funzioni attorno a campi mutabili. Il closest I've found dicecampi di registrazione mutabili e {x con ...}

6.7 Espressioni

expr := ... 
    ∣ { expr with field = expr { ; field = expr } [;] } 

...

Records

L'espressione { expr with field1 = expr1 ; … ; fieldn = exprn } costruisce un record fresco con fields field1 … fieldn pari a expr1 … exprn, e tutti gli altri campi che hanno lo stesso valore come nel record expr. In altri termini, restituisce una copia superficiale del record expr, ad eccezione dei campi field1 … fieldn, che vengono inizializzati su expr1 … exprn.

Quella "copia superficiale" verbosità potrebbe essere interpretata nel senso che i campi mutable non menzionati condividono lo spazio di archiviazione o potrebbero fare riferimento a record annidati. Quando ho prova (usando "toplevel di OCaml, versione 4.00.1") così

type t = { mutable x : int; mutable y: int } 
let a = {x=42;y=123} 
let b = { a with y=124} 
let _ = a.x <- 43 
let _ = Printf.printf "b.x=%d\n" b.x 
;; 

ottengo un risultato che indica che b.x non alias a.x:

b.x=42 
type t = { mutable x : int; mutable y : int; } 
val a : t = {x = 43; y = 123} 
val b : t = {x = 42; y = 124} 

che mi rende molto felice, ma voglio fare in modo che

{ e with fi=x } 

è lo zucchero in modo efficace sintattico per qualcosa come

0.123.516,410617 millions

e che i campi non possono essere supportati da un ref che un'implementazione potrebbe riutilizzare anziché allocare una nuova memoria mutabile.

+1

Così si vuole solo di confermare che '{e con fi = x}' è lo zucchero in modo efficace sintattico per '(lasciare tmp = e in {F0 = tmp.f0; ... fi-1 = tmp. fi-1; fi = x; fi + 1 = tmp.fi + 1; ...; fn = tmp.fn}) '... ecc.? –

+0

@RobertHarvey, Un puntatore ad altri documenti o una spiegazione di come leggere questi documenti sarebbe utile, ma qualsiasi cosa da qualcuno che sa cosa sia e non è un comportamento indefinito sarebbe d'aiuto. –

risposta

3

Ovunque ho visto, "copia superficiale" significa, trasferire semplicemente tutti i componenti come se fossero assegnati, anche in lingue in cui tutti i campi sono sempre mutabili, come Java. Quindi in questo caso (let tmp=e in { f0=tmp.f0; … fi-1=tmp.fi-1; fi=x; fi+1=tmp.fi+1; …; fn=tmp.fn }) è esattamente ciò che dovrebbe significare.

+0

Se 'mutable' sono stati implementati come zucchero sintattico usando' ref' così '{mutable i: int}' è zucchero sintattico per '{i: int ref}' e '{i = 42}' quando 'i' è mutabile è zucchero sintattico per '{i = ref 42}', quindi una copia superficiale copierebbe la cella ref. Non riesco a trovare la sezione dei documenti che specifica se il campo del record mutabile è un puntatore immutabile a un 'ref' aliasabile che vive al di fuori del record. –

+4

@Mike: In OCaml, 't ref' è zucchero per' {contenuto mutabile: t} '(come indicato nel manuale da qualche parte), quindi puoi tranquillamente pensare che' mutable' non sia definito in termini di indirezione tramite 'ref '. ;) –

+0

@AndreasRossberg, Grande. I campi di registrazione 'mutabili' sono i primitivi di memoria mutabili su cui sono costruite altre astrazioni. Molte grazie. Per la cronaca, i riferimenti manuali sono [2.2 Mutable] (http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-core.html#mutable) che dice "In effetti, in OCaml, i riferimenti non sono primitivi: sono casi speciali di mutevole record ". e questo è ribadito nel [Pervasives ocamldoc] (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#TYPEref). –

Problemi correlati