Pergunta

Eu wikipedia cheque já, e pesquisei, mas eu ainda não posso envolver minha mente em torno de como pass-por-nome obras em ALGOL 60.

Foi útil?

Solução

Eu encontrei uma boa explicação em passam-Nome Parâmetro . Essencialmente, o corpo de uma função é interpretado no momento da chamada após textualmente substituindo os parâmetros reais para dentro do corpo função. Neste sentido, o método de avaliação é semelhante à de C pré-processador macros.

Ao substituir os parâmetros reais para o corpo da função, o corpo da função pode ler e gravar os parâmetros dados ambos. Neste sentido, o método de avaliação é semelhante à passagem por referência. A diferença é que uma vez que com pass-by-name o parâmetro é Avaliados dentro da função, um parâmetro como a[i] depende do valor atual de i dentro da função, em vez de se referindo ao valor em a[i] antes que a função foi chamada.

A página I ligada acima tem mais alguns exemplos de onde pass-by-name é tanto útil, e perigoso. As técnicas possibilitada pela passagem por nome são largamente ultrapassada hoje por outras técnicas, mais seguras, como passagem por referência e funções lambda.

Outras dicas

Eu estou supondo que você média de chamada por nome em ALGOL 60.

Call-by-name é semelhante a chamar por referência em que você pode alterar o valor do passado em parâmetro. Ela difere da chamada por referência em que o parâmetro é não avaliadas antes do procedimento é chamado, mas em vez disso é avaliada preguiçosamente. Ou seja, ele é avaliado quando e somente quando o parâmetro é realmente usado.

Por exemplo, suponha que temos uma f(x, y) procedimento e nós passá-lo i e i/2 onde i é inicialmente igual a 10. Se conjuntos f x para 42 e, em seguida, avalia y ele vai ver o valor 21 (enquanto que com chamada por referência ou por valor ainda veria 5). Isso ocorre porque o i/2 expressão não é avaliada até y é avaliada.

De muitas formas isso parece comportar-se como um texto de substituição literal dos parâmetros (com a renomeação de conflitos de nome para evitar). Na prática, porém, isso é implementado utilizando "thunks" (basicamente fechamento) para o passado em expressões.

O artigo da Wikipedia sobre mostras dispositivo de Jensen alguns exemplos interessantes de usar chamada pelo nome . Aqui é um deles:

real procedure Sum(k, l, u, ak)
     value l, u;
     integer k, l, u;
     real ak;
     comment k and ak are passed by name;
 begin
     real s;
     s := 0;
     for k := l step 1 until u do
         s := s + ak;
     Sum := s
 end;

No procedimento, o k índice variável e prazo somatório ak são passou pelo nome. Chamada por nome permite que o procedimento para alterar o valor do índice variável durante a execução do loop for. Chamada pelo nome Também faz com que o argumento ak ser reavaliada durante cada iteração o laço. Tipicamente, ak dependerá da mudança (lado-afectada) k.

Por exemplo, o código para calcular a soma dos primeiros 100 termos de uma verdadeira variedade V[] seria:

Sum(i, 1, 100, V[i]).

Para aqueles no futuro:

Conceitos de Linguagens de Programação por John C. Mitchell também foi útil.

Pass-by-name . Talvez o mais estranho característica de Algol 60, em retrospectiva, é o uso de passagem por nome. No passagem por nome, o resultado de uma chamada de procedimento é o mesmo como se o parâmetro formal foram substituídos em o corpo do procedimento. Esta regra para definir o resultado de um procedimento chamar copiando o procedimento e substituindo os parâmetros formais é chamado a regra de cópia Algol 60. Embora a regra de cópia funciona bem para programas funcionais puros, como ilustrada por redução ß em lambda o cálculo, a interacção com o lado efeitos para o parâmetro formal são um um pouco estranho. Aqui está um exemplo programa mostrando uma técnica conhecida como dispositivo de Jensen: uma passagem expressão e uma variável que contém a um procedimento para que o procedimento pode usar um parâmetro para alterar o localização referido pelo outro:


 begin integer i;
        integer procedure sum(i, j);
            integer i, j;
                comment parameters passed by name;
            begin integer sm; sm := 0;
                for i := 1 step 1 until 100 do sm := sm + j;
                sum := sm
            end;
        print(sum(i, i*10 ))
 end

Neste programa, o procedimento soma (i, j), adiciona-se os valores de j como i vai de 1 a 100. Se você olhar para o código, você vai perceber que o procedimento não faz sentido, a menos alterações ao i causar alguma mudança no valor de j; de outro modo, o procedimento apenas computa 100 * j. Na chamada soma (i, i * 10) mostrado aqui, o loop no corpo da soma procedimento adiciona-se o valor de i * 10 como i vai de 1 a 100.

Na verdade, chamada por nome, não é apenas uma curiosidade histórica. Você pode fazer chamadas por nome em arquivos em lote do Windows (e miríade de outras linguagens de script). Sabendo como funciona e como usá-lo efetivamente na programação pode abrir soluções puras para os problemas. Eu sei que ele só está passando cordas através de expansão mais tarde, mas ele pode ser manipulado para ter efeitos semelhantes, como chamada por nome.

call :assign x 1
exit /b
:assign
setlocal enabledelayedexpansion
(endlocal
:: Argument 1 is the name of the variable
set %1=%2
)
exit /b

Flatlander tem um exemplo esclarecedor de como ele funciona em Scala aqui . Suponha que você queira implementar enquanto :

def mywhile(condition: => Boolean)(body: => Unit): Unit =
  if (condition) {
    body
    mywhile(condition)(body)
  }

Podemos chamar isso da seguinte forma:

var i = 0
mywhile (i < 10) {
  println(i)
  i += 1
}

Scala não é Algol 60, mas talvez ele lança alguma luz.

Você pode passar "nome" na forma simbólica de uma variável que permite que ele seja tanto atualizados e acessados ??simultaneamente. Como exemplo, digamos que você quer triplicar uma variável x que é do tipo int:

start double(x);
real x;
begin
x : = x * 3
end;

ALGOL foi projetado para algoritmos matemáticos. I como a função soma como um exemplo de chamada pelo nome.

Desculpe o meu ALGOL é um enferrujado pouco a sintaxe provavelmente não é certo.

.FUNCTION SUM(var,from,to,function)
.BEGIN
  .REAL sum =0;
  .FOR var = from .TO to .DO sum = function;
  return sum;
.END

Você poderia que a soma uso como

  Y = sum(x,1,4,sum(y,3,8,x+y));

No exemplo acima a soma interior (y, 3,8, x + y) poderia gerar uma função não identificada para passar para a chamada soma exterior. As variáveis ??x e y não são passados ??por valor, mas pelo nome. No caso de variáveis ??chamar pelo nome é equivalente a chamar por referência endereço em C. Ele fica um pouco confuso quando recursão está envolvido.

Borrows feita máquinas ALGOL. Eles tinham 48 palavra memória bit com 3 bits de bandeira. Os bits bandeira implementou o cal pelo nome de ALGOL. era uma máquina de pilha de modo quando a função foi carregado na pilha a chamada pelo nome fag faria com que ele a ser chamado. O compilador geraria funções sem nome quando as expressões foram utilizadas como argumentos. Uma variável seria uma referência indireta simples. Um erro poderia ocorrer escrita para uma função.

Eu sei que estou juntando tarde para o clube e isso não é necessariamente uma resposta, mas eu queria acrescentar uma coisa que poderia ajudar a esclarecer um pouco. Eu sempre pensei do Algol passagem por nome como um processo similar a quando os ++ directivas C pré-processador (macros, especificamente) substitui o nome de alguma função / variável com a peça real de código durante o tempo de compilação. O pass-by-name essencialmente substitui o nome do parâmetro formal com o parâmetro real, e executa. Eu nunca escritos em Algol, mas eu ouvi esse nome passa-por-terá o mesmo resultado que pass-by-reference 's C ++.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top