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.
let bottom = bottom
let ignore x = 1
ignore bottom
Wenn Sie auswerten bottom
, wird es nicht beendet: bottom
erweitert sich zu sich selbst, ad nauseam. Der Begriff bottom
kann keinen Wert haben. Aber wenn Sie auswerten ignore bottom
, ist der Wert 1
. Dies zeigt, dass für den Aufruf der Funktion ignore
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.)
a
"?