Haskell no tiene referencias (una referencia es un objeto mutable y Haskell no tiene objetos mutables (directamente accesibles)). Por lo tanto, las llamadas a funciones usan semántica de valor, como por defecto. De hecho, esta es una propiedad importante de los lenguajes funcionales puros: una función no puede modificar su argumento.
La semántica del valor no implica que la copia ocurra debajo del capó. Solo necesita copiar la parte de un valor que la función modifica, lo que en un lenguaje puro significa que nunca necesita copiar nada.
Sin embargo, esta no es toda la historia. En cierto sentido, Haskell tiene semántica de referencia.
Si bien no tiene sentido probar si una función modifica su argumento (nunca lo hace), puede probar si una función usa (parte de) su argumento. Proporcione un argumento que no termine. Si la llamada a la función termina, usted sabe que la función no usó su argumento.
let bottom = bottom
let ignore x = 1
ignore bottom
Si evalúa bottom
, no termina: se bottom
expande a sí mismo, hasta la saciedad. El término bottom
no puede tener un valor. Pero si evalúa ignore bottom
, el valor es 1
. Esto muestra que llamar a la función ignore
no requiere calcular el valor de su argumento. En este sentido, Haskell tiene una semántica de referencia: lo que recibe una función no es un valor, sino algo que permite encontrar este valor. El término técnico es llamar por nombre (en oposición a llamar por valor ).
(Más precisamente, las implementaciones de Haskell usan llamada por necesidad . En llamada por valor, el argumento de una función se evalúa exactamente una vez, justo antes de llamar a la función. En llamada por nombre, el argumento se evalúa cada vez que se usa, lo que puede variar desde nunca hasta tantas veces como lo desee la función. En caso de necesidad, el argumento se evalúa como máximo una vez: se evalúa la primera vez que se usa, o nunca si no se usa).
a
"?