Test preliminare del valore / semantica di riferimento di Haskell

8

Nei linguaggi imperativi, è banale escogitare un test di programmazione dell'uso della lingua della "semantica del valore" o della "semantica di riferimento". Si potrebbe fare quanto segue e controllare il valore di a (dove Vertex {one, two, three :: Integer} ):

a := Vertex 3 4 5
b := a
one b   :=  6
two b   :=  8
three b := 10

Tuttavia, poiché le variabili sono immutabili nei linguaggi funzionali, questo test non funzionerà in tali lingue.

So molto poco di Haskell (e della programmazione funzionale in generale), ma la mia comprensione è che utilizza semantica del valore. È possibile escogitare un esperimento di programmazione che distingua tra un "record di riferimento" e un "record di val" in Haskell?

    
posta David Chouinard 23.01.2013 - 17:49
fonte

3 risposte

9

Non esiste tale test, perché, senza mutabilità, la distinzione non è significativa (come hai dimostrato).

    
risposta data 23.01.2013 - 19:38
fonte
9

Haskell non ha riferimenti (un riferimento è un oggetto mutabile e Haskell non ha oggetti mutabili (direttamente accessibili)). Pertanto le chiamate di funzione utilizzano la semantica del valore, una sorta di impostazione predefinita. Questa è infatti una proprietà importante dei linguaggi funzionali puri: una funzione non può modificare il suo argomento.

La semantica del valore non implica che la copia avvenga sotto il cofano. Hai solo bisogno di copiare la parte di un valore che la funzione modifica, che in un linguaggio puro significa che non hai mai bisogno di copiare nulla.

Tuttavia, questa non è l'intera storia. In un certo senso, Haskell ha semantica di riferimento.

Anche se non ha senso verificare se una funzione modifica il suo argomento (non lo fa mai), puoi verificare se una funzione usa (parte) il suo argomento. Forniscilo con un argomento che non termina. Se la chiamata alla funzione termina, sai che la funzione non ha usato il suo argomento.

let bottom = bottom
let ignore x = 1
ignore bottom

Se valuti bottom , non termina: bottom si espande a se stesso, ad nauseam. Il termine bottom non può avere un valore. Ma se valuti ignore bottom , il valore è 1 . Questo dimostra che chiamare la funzione ignore non richiede il calcolo del valore del suo argomento. In questo senso, Haskell ha una semantica di riferimento: ciò che una funzione riceve non è un valore ma qualcosa che consente di trovare questo valore. Il termine tecnico è chiama per nome (al contrario di chiamata per valore ).

(Più precisamente, le implementazioni Haskell usano chiamata per necessità . In call by value, l'argomento di una funzione viene valutata esattamente una volta, appena prima di chiamare la funzione.In chiamata per nome, l'argomento viene valutato ogni volta che viene utilizzato, che può variare da mai a quante volte desidera la funzione. valutato al massimo una volta: viene valutato la prima volta che viene utilizzato, o mai se non viene utilizzato.)

    
risposta data 23.01.2013 - 22:56
fonte
7

È impossibile distinguere tra loro. Ciò significa che il compilatore è libero di scegliere di utilizzare qualsiasi semantica ritenga opportuno per prestazioni ottimali.

In particolare, i linguaggi funzionali sono tipicamente descritti come aventi semantica del valore, perché corrispondono al nostro modello concettuale di essi, ma sono spesso implementati usando la semantica di riferimento perché è più efficiente. (Non c'è bisogno di copiare qualcosa che non può essere modificato!)

    
risposta data 23.01.2013 - 20:52
fonte

Leggi altre domande sui tag