In imperativen Sprachen ist es trivial, einen Programmiertest für die Verwendung von "Wertesemantik" oder "Referenzsemantik" durch die Sprache zu entwickeln. Man könnte folgendes tun und den Wert von a
(wo Vertex {one, two, three :: Integer}
) überprüfen :
a := Vertex 3 4 5
b := a
one b := 6
two b := 8
three b := 10
Da Variablen in funktionalen Sprachen unveränderlich sind, funktioniert dieser Test in solchen Sprachen nicht.
Ich weiß sehr wenig über Haskell (und die funktionale Programmierung im Allgemeinen), aber ich verstehe, dass sie Wertesemantik verwendet. Ist es möglich, ein Programmierexperiment zu entwickeln, das in Haskell zwischen einem "Ref-Datensatz" und einem "Val-Datensatz" unterscheidet?
functional-programming
haskell
David Chouinard
quelle
quelle
a
"?Antworten:
Es gibt keinen solchen Test, da die Unterscheidung ohne Veränderbarkeit nicht aussagekräftig ist (wie Sie gezeigt haben).
quelle
IORef
,MVar
usw.) veränderlich sind und sich als Referenzen verhalten ( hpaste.org/81192 )Haskell hat keine Referenzen (eine Referenz ist ein veränderbares Objekt, und Haskell hat keine (direkt zugänglichen) veränderlichen Objekte). Daher verwenden Funktionsaufrufe standardmäßig eine Wertesemantik. Dies ist in der Tat eine wichtige Eigenschaft reiner funktionaler Sprachen: Eine Funktion kann ihr Argument nicht ändern.
Die Wertesemantik bedeutet nicht , dass das Kopieren unter der Haube erfolgt. Sie müssen nur den Teil eines Werts kopieren, den die Funktion ändert. In einer reinen Sprache bedeutet dies, dass Sie niemals etwas kopieren müssen.
Dies ist jedoch nicht die ganze Geschichte. In gewissem Sinne hat Haskell Referenzsemantik.
Während es sinnlos ist zu testen, ob eine Funktion ihr Argument ändert (was sie niemals tut), können Sie testen, ob eine Funktion ihr Argument verwendet (einen Teil davon). Geben Sie ein Argument an, das nicht endet. Wenn der Funktionsaufruf beendet wird, wissen Sie, dass die Funktion ihr Argument nicht verwendet hat.
Wenn Sie auswerten
bottom
, wird es nicht beendet:bottom
erweitert sich zu sich selbst, ad nauseam. Der Begriffbottom
kann keinen Wert haben. Aber wenn Sie auswertenignore bottom
, ist der Wert1
. Dies zeigt, dass für den Aufruf der Funktionignore
nicht der Wert ihres Arguments berechnet werden muss. In diesem Sinne hat Haskell eine Referenzsemantik: Was eine Funktion empfängt, ist kein Wert, sondern etwas, mit dem dieser Wert gefunden werden kann. Der Fachbegriff lautet Call by Name (im Gegensatz zu Call by Value ).(Genauer gesagt verwenden Haskell-Implementierungen call by need . Bei call by value wird das Argument einer Funktion genau einmal ausgewertet, unmittelbar bevor die Funktion aufgerufen wird. Bei call by name wird das Argument jedes Mal ausgewertet, wenn es verwendet wird von nie bis so oft, wie die Funktion es wünscht. Bei Bedarf wird das Argument höchstens einmal ausgewertet: Es wird bei der ersten Verwendung ausgewertet oder niemals, wenn es nicht verwendet wird.)
quelle
Es ist unmöglich , zwischen ihnen zu unterscheiden. Dies bedeutet, dass der Compiler frei wählen kann, welche Semantik er für eine optimale Leistung für geeignet hält.
Insbesondere werden funktionale Sprachen in der Regel als Wertsemantik beschrieben , da dies unserem konzeptionellen Modell entspricht. Sie werden jedoch häufig mithilfe der Referenzsemantik implementiert , da dies effizienter ist. (Sie müssen nichts kopieren, was nicht geändert werden kann!)
quelle