2015-07-19 10 views
5

Sto leggendo Harper's Intro su SML e sono un po 'confuso sulle celle di riferimento. A p. 114, dà il seguente esempio:Standard ML: Confusione sulle celle di riferimento

val r = ref 0 
val s = ref 0 
val _ = r := 3 
val x = !s + !r 
val t = r 
val _ = t := 5 
val y = !s + !r 
val z = !t !r 

"Dopo l'esecuzione di tali attacchi, x è destinata a 3, y è tenuto a 5, e z è destinato a 10"

Ecco la mia traccia del suo codice:

val r = ref 0 //allocates storage for r and sets to 0 
val s = ref 0 //allocates storage for s and sets to 0 
val _ = r := 3 //sets r = 3 
val x = !s + !r //sets x = 0 + 3 = 3 
val t = r //sets t = 3 
val _ = t := 5 //sets t = 5 
val y = !s + !r //sets y = 0 + 3 = 3 
val z = !t !r //sets z = 5 + 3 = 8 

mio x è corretta (3), ma il mio Y e Z sono entrambe sbagliate (la mia y è 3 invece di 5 e la mia Z è 5 invece di 10).

Dove sto andando storto qui?

Inoltre, perché è necessario val _ = t := 5 anziché semplicemente t := 5?

Grazie, bclayman

risposta

5

val t = r non imposta t su 3. Imposta t come la cella di riferimento identica a r.

Pertanto, quando si esegue t := 5, si imposta su entrambi i contenuti di t e r a 5, poiché entrambi contengono la stessa cella di riferimento.

Come per l'altra domanda, t := 5 è una chiamata di funzione della funzione := : 'a ref * 'a -> unit. Pertanto, t := 5 è un'espressione che restituisce ().

val _ = t := 5 semplicemente getta via () e lo trasforma in una dichiarazione piuttosto che in un'espressione.

+0

Quindi quando val do t = r, e quindi t: = 5, questo in qualche modo cambia anche r? Sembra molto strano ... se avessi cambiato r in 5, mi sarei aspettato che anche tu cambiasse in 5. Ma non viceversa :( – bclayman

+3

* Né * t né r cambia quando viene valutata l'espressione 't: = 5' Entrambi rimangono riferimenti a una posizione specifica in memoria.Valutazione di quell'espressione ha l'effetto collaterale di alterare il contenuto di quella Ovviamente r ora punta a questo nuovo valore - ma non perché lo stesso è stato cambiato.Un'analogia: se sto indicando un cane e tu stai indicando esattamente lo stesso cane, e dico a quel cane di "sedersi" "(e lo fa), staresti indicando un cane seduto - ma non perché in qualche modo ti abbia cambiato. –

3

val t = r rende t un alias per r. Entrambi si riferiscono alla stessa posizione nel negozio. Pertanto, t := 5 ha l'effetto collaterale di modificare il contenuto della posizione di memoria a cui fa riferimento anche r (poiché t e r si riferiscono allo stesso luogo). Quindi

val y = !s + !t 

insiemi y = 0 + 5 = 5.

Lei ha ragione che val _ = t := 5 è fondamentalmente la stessa come t := 5, se il primo sopprime output nella REPL (scartando il valore dell'espressione di assegnazione).