Em linguagens imperativas, é trivial conceber um teste de programação do uso da linguagem de "semântica de valores" ou "semântica de referência". Pode-se fazer o seguinte e verificar o valor de a
(where Vertex {one, two, three :: Integer}
):
a := Vertex 3 4 5
b := a
one b := 6
two b := 8
three b := 10
No entanto, como as variáveis são imutáveis em linguagens funcionais, esse teste não funcionará em tais linguagens.
Sei muito pouco sobre Haskell (e programação funcional em geral), mas entendo que ele usa semântica de valor. É possível conceber um experimento de programação que distingue entre um "registro ref" e um "registro val" em Haskell?
functional-programming
haskell
David Chouinard
fonte
fonte
a
"?Respostas:
Não existe esse teste, porque, sem mutabilidade, a distinção não é significativa (como você demonstrou).
fonte
IORef
,MVar
, etc) são mutáveis e comportam-se como referências ( hpaste.org/81192 )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.
Se você avaliar
bottom
, ele não termina: sebottom
expande para si próprio, ad nauseam. O termobottom
não pode ter um valor. Mas se você avaliarignore bottom
, o valor é1
. Isso mostra que chamar a funçãoignore
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.
fonte
É impossível distinguir entre eles. O que isso significa é que o compilador é livre para optar por usar qualquer semântica que considerar adequada para um desempenho ideal.
Em particular, as linguagens funcionais são normalmente descritas como tendo semântica de valor, porque isso corresponde ao nosso modelo conceitual delas, mas geralmente são implementadas usando semântica de referência, porque é mais eficiente. (Não é necessário copiar algo que não pode ser alterado!)
fonte