-calculus, há codificação de por ou enquanto?

7

No -calculus, podemos codificar aritmética, números, booleanos e até calcular fatoriais de números, como mostrado aqui .λ

Existe codificação de "for" ou "while"?

alim
fonte
6
O cálculo λ está completo, portanto, sim, você pode fazer o mesmo que um loop for ou while. Eu não os chamaria de codificações , como eles são apenas funções, como tudo na λ-cálculo
Euge

Respostas:

11

Certo! Deixe-me mostrar como codificar FOR usando um exemplo.

Suponha que desejemos traduzir um fator FOR simples para o programa

x := 1
for i := 1 to N do
   x := x * i

Reescrevemos como

x := 1
i := 1
repeat N times
   x := x*i
   i := i+1

então colocamos todas as variáveis ​​que usamos em uma tupla (um par é suficiente, aqui)

(x,i) := (1,1)
repeat N times
   (x,i) := (x*i, i+1)

Isso efetivamente aplica a função para o par inicial por vezes.λx,i.xi,i+11,1N

Como pode ser representado como um numeral da Igreja, obtemosN

N(λx,i.xi,i+1)1,1

A sintaxe acima usa algumas coisas além do cálculo lambda simples. Números e aritmética podem ser feitos com precisão usando números da Igreja. Os pares também têm sua própria codificação da Igreja:

x,yλk.kxyλx,y.Mλz.M{zT/x,zF/y}
onde é uma variável fresco, e .zT=λab.aF=λab.b

Se você tiver mais de duas variáveis, poderá generalizar a codificação acima para tuplas ou simplesmente representar tuplas como pares aninhados.


QUANDO é melhor lidar com o uso de recursão: em vez de

while p(x,i) do
   (x,i) := f(x,i)

Onde pé um predicado e fé uma função (parcial), podemos usar algo como

def recFun(x,i):
   if p(x,i):
      return recFun(f(x,i))
   else:
      return (x,i)

No cálculo lambda, a recursão é obtida usando um combinador de ponto fixo , por exemplo, da Igreja ou Turing . Temos algo comoYΘ

Y(λr.λx,i.if pxi then r(fx,i) else x,i)

onde supor que os booleanos sejam codificados pela Igreja.if b then t else ebte

Observe também que WHILE é (estritamente) mais poderoso que FOR. Todo FOR pode ser codificado como WHILE, portanto, essa técnica de codificação também pode ser usada para FOR.

chi
fonte
9

Existem codificações de loops, mas elas não funcionam exatamente como os loops com os quais você está acostumado, porque o cálculo lambda não é uma linguagem imperativa. O cálculo lambda não tem efeitos colaterais (é uma linguagem puramente funcional ); portanto, o equivalente exato de um loop seria inútil.

Estado explícito

Um programa imperativo pode ser traduzido para uma linguagem puramente funcional, passando todo o estado explicitamente como uma variável no programa. Vou usar a sintaxe Python para pseudocódigo imperativo; ele deve ser transparente na maior parte, com a indicação de que (a, b) = f(…)os meios que a chamada para a função fretorna um par e ae bsão atribuídas do primeiro e segundo componente do par, respectivamente. Considere um loop

while test_condition():
    do_stuff()

Vamos tornar o estado explícito.

state = initial_state
(state, cond) = test_condition(state)
while cond:
    (state, cond) = test_condition(do_stuff(state))

Podemos traduzir isso em uma chamada recursiva. def loop(state):define uma função chamada loop.

def loop(state):
    (state, cond) = test_condition(state)
    if cond: return loop(do_stuff(state))
    else: return state
state = loop(initial_state)

Isso usa apenas os seguintes conceitos, todos os quais podem ser expressados ​​facilmente no cálculo lambda:

  • Chamadas de funções: conceito nativo
  • Atribuições de variáveis locais sem reatribuição: passe o valor para uma função auxiliar
  • Pares: Pares da Igreja
  • Booleanos: Booleanos da igreja
  • Recursão: combinadores de ponto fixo

E assim podemos definir uma whilefunção para uma condição ( ) e um corpo ( ): Ctest_conditionBdo_stuff

while:=λC.λB.fix(λf.λs.(λp.BODY(firstp)(secondp))(Cs))where BODY=λs.λc.ifc(f(Bs))s

Os loops variam dependendo da linguagem de programação, mas são sempre um caso especial de loops while, para que possam ser codificados da mesma maneira. Se o idioma de origem limitar a expressividade dos loops for, pode haver codificações mais simples. Por exemplo, “repetir vezes” é simplesmente composição da função vezes, onde a função é a transformação de estado que constitui o corpo do loop, e se é um numeral da Igreja, isso simplesmente se aplica à função do corpo do loop.nnnn

Adicionando estado ao idioma

Uma abordagem alternativa ao estado é estender o cálculo lambda com primitivas de manipulação de estado. Se você fizer isso, a ordem da avaliação se tornará importante. Nesse caso, um loop while pode ser expresso diretamente com recursão.

whileimperative:=λC.λB.fix(λf.ifC(B;f)())
Gilles 'SO- parar de ser mau'
fonte