“Ordem normal” e “chamada por nome” são a mesma coisa?

9

Eu estava estudando o livro Estrutura e Interpretação de Programas de Computador e na seção 1.1.5 O Modelo de Substituição para Aplicação de Procedimentos, o autor explica os conceitos de ordem normal e ordem de aplicação , que acredito ter entendido bem.

Agora, estou fazendo um curso sobre o Coursera chamado Princípios de Programação de Funções em Scala e aí o professor Martin Odersky (que baseou grande parte de seu curso no livro citado acima) explica os mesmos conceitos sob os nomes de chamada por nome e chamada - por valor .

Em seu curso, o professor Odersky diz que o modelo de substituição é baseado no Cálculo Lambda, então consultei um livro na minha biblioteca Uma introdução à programação funcional Embora o Cálculo Lambda e na página 22, o autor defina os termos como ordem de aplicação e ordem normal . Curiosamente, em sua definição, ele diz que a ordem aplicativa é como a chamada por valor de Pascal, enquanto a ordem normal é como a chamada por nome de Algol.

O uso das palavras "é como" em sua explicação é o que me fez duvidar. Assim, minhas perguntas:

  • Esses dois termos são equivalentes ou existem diferenças sutis?
  • Posso usar um ou outro de forma intercambiável sem correr o risco de cometer um erro no significado que eles transmitem?
  • Você conhece algum motivo que justifique a existência de terminologia diferente para se referir à mesma coisa?
edalorzo
fonte
1
Este artigo da Wikipedia afirma que, ao contrário da ordem normal, "uma estratégia de chamada por nome não avalia dentro do corpo de uma função não aplicada". Nenhuma citação específica é dada embora.
Chrisaycock #
4
Apenas para referência, você sabe que Martin Odersky é o principal designer da Scala, certo?
KChaloux

Respostas:

7

A avaliação normal de pedidos e a avaliação chamada por nome não são exatamente a mesma coisa. Na avaliação de ordem normal, a função mais externa é avaliada antes de qualquer um de seus argumentos, e esses argumentos são avaliados apenas se necessário. Na avaliação de chamada por nome, os argumentos são efetivamente copiados no corpo da função mais externa e, em seguida, essa função é avaliada. Nos dois casos, a função mais externa é tecnicamente avaliada antes dos argumentos, mas, em chamada por nome, os argumentos são avaliados sempre que são usados ​​(zero, uma ou várias vezes). Em ordem normal, os argumentos da função são avaliados no mínimo somente quando necessário pela primeira vez (geralmente zero ou uma vez).

Assim, a avaliação normal da ordem deixa em aberto a possibilidade de memorizar os argumentos como uma otimização (às vezes chamada de chamada por necessidade), enquanto a chamada por nome não. Assim, pode-se dizer que a avaliação por chamada é um caso especial de avaliação de ordem normal. Em outras palavras, a avaliação de ordem normal refere-se à abordagem geral de avaliar uma função antes de seus argumentos, enquanto a avaliação por chamada refere-se a uma técnica específica para implementar a avaliação de ordem normal.

Como exemplo, dado f(x, y) = sqrt(x*x + y*y)que poderíamos ter duas maneiras de implementar f(a+b, c+d)com a avaliação normal de pedidos:

Memoized:

t1 = a+b;
t2 = c+d;
return sqrt(t1*t1 + t2*t2);

Chamada por nome:

return sqrt((a+b)*(a+b) + (c+d)*(c+d));

Como você pode ver, se a chamada para f incluir outras chamadas de função (ou seja f(random(1,100), ask_user_for_value())), as duas terão um comportamento muito diferente. A versão memorizada quadrará um único número aleatório e solicitará ao usuário um valor apenas uma vez, enquanto a versão chamada por nome multiplicará dois números aleatórios e solicitará ao usuário um valor duas vezes.

Para saber mais sobre esses conceitos, recomendo a leitura da página da estratégia de avaliação na Wikipedia e /cs/7702/applicative-order-and-normal-order-in-lambda-calculus .

Randall Cook
fonte
Obrigado, @edalorzo. Se você achou valioso, considere aceitá-lo. :)
Randall Cozinhe