Haskell não possui referências (uma referência é um objeto mutável e Haskell não possui objetos mutáveis (diretamente acessíveis)). Portanto, as chamadas de função usam semântica de valores, como por padrão. Essa é de fato uma propriedade importante das linguagens funcionais puras: uma função não pode modificar seu argumento.
A semântica do valor não implica que a cópia ocorra sob o capô. Você só precisa copiar a parte de um valor que a função modifica, o que em uma linguagem pura significa que você nunca precisa copiar nada.
No entanto, essa não é a história toda. De certa forma, Haskell tem semântica de referência.
Embora não faça sentido testar se uma função modifica seu argumento (nunca o faz), você pode testar se uma função usa (parte de) seu argumento. Forneça um argumento que não termine. Se a chamada da função terminar, você sabe que a função não usou seu argumento.
let bottom = bottom
let ignore x = 1
ignore bottom
Se você avaliar bottom
, ele não termina: se bottom
expande para si próprio, ad nauseam. O termo bottom
não pode ter um valor. Mas se você avaliar ignore bottom
, o valor é 1
. Isso mostra que chamar a função ignore
não requer o cálculo do valor de seu argumento. Nesse sentido, Haskell tem uma semântica de referência: o que uma função recebe não é um valor, mas algo que permite que esse valor seja encontrado. O termo técnico é chamar pelo nome (em vez de chamar pelo valor ).
(Mais precisamente, as implementações de Haskell usam chamada por necessidade . Na chamada por valor, o argumento de uma função é avaliado exatamente uma vez, pouco antes de chamar a função. Na chamada pelo nome, o argumento é avaliado toda vez que é usado, que pode variar de nunca a quantas vezes a função desejar. Na chamada por necessidade, o argumento é avaliado no máximo uma vez: é avaliado na primeira vez em que é usado ou nunca se não for usado.
a
"?