Buscar

Cálculo Lambda: Uma Introdução

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 12 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 12 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 12 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Sumário
1. Introdução
2. História
3. Definição
4. Estilo Church vs Estilo Curry
5. Redução
6. Confluência
7. Conversão
8. Atribuição de Tipo
9. Tipos de Dados
10. Recursão
11. Conclusão
12. Referências
Introdução
Para a ciência da computação, o cálculo lambda, também escrito como cálculo-
λ, é um sistema formal que estuda funções recursivas computáveis, pelo Teorema de
Recursão, e fenômenos relacionados, como variáveis ligadas e substituição. A
principal característica são as entidades que podem ser utilizadas como argumento e
retornadas como valores de outras funções. Ambos os conceitos são definidos
indutivamente.
Programação funcional é um paradigma de programação que trata a
computação como uma avaliação de funções matemáticas e que evita estados ou
dados mutáveis. Ela enfatiza a aplicação de funções, em contraste da programação
imperativa, que enfatiza mudanças no estado do programa.
Linguagens de programação funcionais, especialmente as puramente
funcionais, tem sido mais usadas academicamente que no desenvolvimento comercial
de software. Entretanto, algumas linguagens notáveis usadas na indústria e no
comércio incluem Erlang (aplicações concorrentes), R (estatística), Mathematica
(matemática simbólica) J,K(análise financeira) e XSLT. O cálculo lambda teve uma
importante influência na programação funcional, principalmente nas linguagens de
programação APL e Lisp, e mais recentemente ML, Haskell, OCaml, F# e Elixir. As
funções são tratadas como valores de primeira importância, o que é o mesmo que
dizer que funções podem ser parâmetros ou valores de entrada para outras funções e
podem ser os valores de retorno ou saída de uma função.
Funções podem ser nomeadas, como em outras linguagens, ou definidas
anonimamente (algumas vezes durante a execução do programa) usando uma
abstração lambda e usadas como valores em outras funções. Linguagens funcionais
também permitem que funções sejam do tipo curry. Currying é uma técnica para
reescrita de funções com múltiplos parâmetros como a composição de funções de um
parâmetro. A função do tipo curry pode ser aplicada apenas a um subconjunto de seus
parâmetros. O resultado é uma função onde os parâmetros neste subconjunto são
agora fixados como constantes, e os valores do resto dos parâmetros ainda não são
especificados. A maioria da Linguagens de Programação Funcional são semelhantes e
diferem somente em aspectos sintáticos. 
Começamos por introduzir os termos e explicar o papel do símbolo λ como um
operador de ligação que realiza a substituição.
História
Funções desempenham um papel proeminente na descrição da semântica de
uma linguagem. O cálculo lambda é uma coleção de diversos sistemas formais
baseadas em funções, criada por Alonzo Church em 1936, professor em Princeton,
EUA (1929–1967) e UCLA (1967–1990),com a intenção de capturar os aspectos mais
simples que operadores e funções podem ser combinados para formar outros
operadores, servindo como ligação entre linguagens funcionais de alto nível e suas
implementáveis de baixo nível. É uma linguagem que preza pela simplicidade,
exigindo somente algumas construções sintáticas de uma semântica simples.
As linguagens de programação funcionais, como Miranda, Haskell,Lisp,
Orwell, ML, são baseadas no Lambda Cálculo, sendo esta ser considerada a menor
linguagem de programação universal. Trata-se de uma linguagem expressiva, a qual é
suficientemente poderosa para expressar todos os programas funcionais e, por
conseguinte, todas as funções computáveis. Isto significa que, com uma
implementação do cálculo lambda, pode-se implementar qualquer linguagem
funcional através da implementação de um compilador desta para o cálculo lambda. 
Definição
O cálculo lambda consiste de uma linguagem de termos lambda junto com uma
teoria equacional, tendo funções como fórmulas.
Pode ser visto como uma linguagem de programação abstrata em que funções podem
ser combinadas para formar outras funções, de uma forma pura.
A linguagem do cálculo lambda usa um alfabeto S constituído de um conjunto
de variáveis(v1, v2,v3,vn) um abstraidor (lambda) e agrupadores(.). O cálculo lambda
estende a ideia de uma linguagem de expressões para incluir funções. Onde
normalmente escreveríamos, por exemplo, f : x → x^3, e então consideramos A =
f(4), em cálculo lambda escreveríamos apenas A = (λx.x^3 )(4). Uma vantagem da
notação lambda é que ela nos permite falar facilmente sobre funções de ordem
superior, isto é, funções cujas entradas e / ou saídas são suas próprias funções.
Expressões lambda são escritas na forma prefixa, com os argumentos lado a lado.
Termos Lambda:
 
Um termo lambda, denotado pelas letras M, N,O, P,..é um elemento da linguagem L,
onde S* L definido da seguinte forma: 
 - ti é termo lambda;
- dado A, (λ ti .A) é termo lambda, chamado de abstração lambda;
- dados dois termos lambda A, B então (AB) é termo lambda, chamado de aplicação;
- e nada mais é termo lambda.
Abstrações lambda são construções em cálculo lambda que denotam funções novas,
não embutidas em um cálculo específico. 
Um programa Lambda se escreve como um conjunto de expressões lambda.
Normalmente, usando notação simplificada encontra-se o símbolo lambda seguido de
lista de variáveis. Limitando estas variáveis vem um ponto ".'', seguido pelo corpo da
função. As variáveis são chamadas de parâmetros formais e diz-se que o lambda os
liga.
Funções que operam em funções: 
Em cálculo lambda, funções são consideradas como valores, então elas podem servir
de entrada para outras funções, e funções podem retornar funções como saída. Por
exemplo, λy.y representa a função identidade y → y, e ( λy.y)x representa a função
identidade aplicada a x. E assim, (λy.x) representa a função constante y→x, uma
função que sempre retorna, independentemente da entrada. . É importante ressaltar
que a aplicação de funções é associativa à esquerda, então ( λy.y)x z=(( λy.y)x)z.
Variáveis Livres e ligadas: 
As variáveis livres de um termo são aquelas variáveis que não são ligadas por uma
abstração lambda. Ou seja, as variáveis livres de y são apenas y; as variáveis livres de
λy.t são as variáveis livres de t, com y removido, e as variáveis livres de tp são a
união das variáveis livres de t e p. Por exemplo, o termo lambda representado pela
função identidade λy.y não possui variáveis livres, mas a função constante λy.x tem a
variável livre x. As variáveis ligadas são as que são ligadas por λ na expressão. Em
λy.t , por exemplo, y é a variável ligada.
Substituição de variáveis:
Suponha que p, q e r são termos lambda e x e y são variáveis. A notação p[x:=r]
indica a substituição de x por r em p,de modo que:
Funções Embutidas e Constantes:
Funções embutidas como + não existem no cálculo lambda na sua forma mais pura.
Para fins práticos, uma extensão que as suporte é útil. Estas incluem funções
aritméticas (como +, –, *, /), constantes (como 0, 1,...), funções lógicas (como AND,
NOT, OR,...) e constantes lógicas (TRUE, FALSE). 
Também incluímos uma função condicional, cujo valor é descrito pelas regras de
redução abaixo:
IF TRUE E t E f ->E t
IF FALSE E t E f ->E f
Construtores de dados em cálculo lambda serão introduzidos inicialmente através da
definição de três funções embutidas: Cons, Head e Tail. Cons constrói um objeto
composto, o qual pode ser desmantelado com Head and Tail operação é descrita pelas
seguintes regras de redução:
HEAD (CONS a b) → a
TAIL (CONS a b) → b
Além dessas funções, define-se a constante NIL, o valor nulo.
A escolha exata de funções embutidas é arbitrária.
Estilo Church vs Estilo Curry 
De um modo geral, existem duas maneiras de atribuição de significado para ocálculo lambda simplesmente tipado, às vezes chamado intrínseco vs extrínseco, ou
estilo Church vs estilo Curry.Uma semântica estilo Church apenas atribui significado
a termos bem tipados, ou mais precisamente, atribui significado diretamente por
derivações de tipagem. O efeito disso é que é possível se atribuir significados
diferentes a termos que se diferenciam apenas por anotações de tipos. Por exemplo, o
termo identidade nos inteiros (λx : int.x) e o termo identidade nos booleanos(λx :
bool.x) podem significar coisas diferentes. Entretanto, uma semântica estilo Curry
atribui significado para termos independente da tipagem, como seriam interpretados
em uma linguagem não tipada. Nesta visão significam a mesma coisa (isto é, λx.x).
A distinção entre semântica intrínseca e extrínseca é às vezes associada a
presença ou não de anotações nas abstrações lambda, mas estritamente falando esse
uso é impreciso. É possível se definir uma semântica estilo Curry em termos anotados
simplesmente ignorando os tipos (através da remoção de tipos, como também é
possível prover uma semântica estilo Church a termos não anotados quando os tipos
podem ser deduzidos do contexto. A diferença essencial entre essas duas abordagens
é apenas como as regras de tipagem são vistas na definição da linguagem, ou como
um formalismo para verificação de propriedades de uma linguagem fundamental
mais primitiva. Maior parte da diferença das interpretações semânticas discutidas
abaixo podem ser vistas sob uma ótica Church ou Curry. 
Redução
A redução também é útil para uma análise de convertibilidade. O teorema de
Church-Rosser diz que se dois termos são conversíveis, então há um termo para o
qual ambos reduzem. Em muitos casos, a inconvertibilidade de dois termos pode ser
provada mostrando que eles não reduzem para um termo comum.
Definição: 
Uma relação binária R em Λ é chamada compatível se:
M R N (ZM) R (ZN), ⇒
(MZ) R (NZ) e
 (λx.M) R (λx.N). 
Uma relação de congruência em Λ é uma relação de equivalência compatível.
Uma relação de redução em Λ é uma relação compatível, reflexiva e transitiva.
Definição:
As relações binárias → β, → β e = β em Λ são definidas indutivamente do seguinte
modo:
(i) 1. (λx.M)N →β M[x := N];
2. M →β N ZM →β ZN, MZ →β NZ e λx.M →β λx.N.⇒
(ii) 1. M → β M;
2. M →β N M → β N;⇒
3M → β N, N → β L M → β L ⇒
(iii) 1. M → β N M =β N;⇒
2.M =β N N =β M;⇒
3 M =β N, N =β L M =βL. ⇒
Essas relações são declaradas da seguinte maneira:
M → β N : Mβ-reduz para N;
 M →β N : Mβ-reduz para N em um passo;
 M =β N : M é β-conversível para N. 
Por definição → β é compatível, → β é uma relação de redução e = β é uma relação
de congruência.
Definição: O termo redex, significa expressão redutível. refere-se a sub-termos que
podem ser reduzidos por uma das regras de redução.
 (i) Um β-redex é um termo da forma (λx.M) N. Nesse caso M [x: = N] é o seu
contratual.
(ii) Um termo λ M é uma forma β-normal (β-nf) se não tiver um β-redex como
subexpressão.
(iii) Um termo M tem uma forma β-normal se M = β N e N for um β-nf, para alguns
N.
Seja M um β-nf. Então:
M → β N N ≡ M.⇒
Prova: Isto é verdadeiro se → β é substituído por → β. Então o resultado segue por
transitividade.
Confluência
Pode ser que um termo lambda ofereça muitas oportunidades de redução ao
mesmo tempo. Para que todo o cálculo tenha sentido, é necessário que o resultado de
um cálculo seja independente da ordem de redução. Gostaríamos de expressar esta
propriedade para todos os termos, não apenas para aqueles que têm uma forma
normal. Isso é possível, segundo o teorema de Church-Rosser: 
“Se um termo M pode ser reduzido (em várias etapas) para termos N e P, então existe
um termo Q ao qual tanto N como P podem ser reduzidos (em várias etapas).”
Por razões gráficas óbvias, a propriedade expressa no Teorema da Church-Rosser é
confluênte. Dizemos que a β-redução é confluente.
Conversão
α-conversão: Conversão de renomeação, permitindo alterar nomes de variáveis
ligadas. Por exemplo, a α-conversão de λy.y poderá produzir λx.x. 
As regras para a alfa-conversão não são tão simples. Primeiro, quando a α-conversão
atua em uma abstração, as únicas ocorrências de variáveis que podem ser renomeados
são aqueles que são vinculados a esta mesma abstração. Por exemplo, λy.λy.y poderia
resultar em λx.λy.y, mas não poderia resultar em λx.λy.λx, pois este possui
significado diferente do original.
η−conversão: Conversão de extensionalidade, que quer dizer que duas funções são as
mesmas se e somente se eles dão o mesmo resultado para todos os argumentos
.η−conversão converte entre λy.(f(y) e f sempre que y não aparece livre em f. Por
exemplo:
Sejam: (ly. + 1 y) e (+ 1). Ambas expressões adicionam1 ao argumento. Então , por
η−conversão, a regra da conversão pode ser expressa da seguinte maneira: (ly. F y) ->
F ,desde que y não ocorra livre em F e F denote uma função. 
A conversão-η pode às vezes eliminar uma abstração-l .
Regras de Conversão:
Há três regras de conversão que possibilitam a interconversão de expressões
envolvendo abstrações-λ :
1. Mudança de nome: a conversão-α permite que se troque o nome de
parâmetros formais de uma abstração-λ, enquanto isto for feito de forma consistente.
2. Aplicação de funções: A redução-β permite a aplicação de abstrações-λ a um
argumento através de geração de uma nova instância do corpo da abstração,
substituindo o argumento por ocorrências livres do parâmetro formal. Cuidado
especial deve ser tomado quando o argumento contém variáveis livres.
3. Eliminação de abstrações-λ redundantes: A redução-η pode as vezes eliminar
uma abstração-λ.
Dentro deste contexto, podemos considerar as funções embutidas
(predefinidas) como mais uma forma de conversão. Esta forma de conversão recebe o
nome de conversão-δ.
Atribuição de Tipo
O cálculo lambda é geralmente referido como uma teoria sem tipo, porque cada
expressão (considerada como uma função) pode ser aplicada a outra expressão
(considerada como um argumento). Por exemplo, a função identidade I ≡ λy.y pode
ser aplicada a qualquer argumento y para dar como resultado que mesmo
Y. Em particular, pode ser aplicado a si próprio.
Existem também versões tipadas do cálculo lambda, chamadas de cálculo
lambda simplesmente tipado. Isso é possível com adição de apenas um elemento (o
construtor de tipos: → para construir tipos de funções.Tipos são geralmente objetos
de uma sintática e podem ser atribuídos a termos lambda. Se P é um termo e um tipo I
é atribuído a P, então dizemos 'P tem tipo I' ou 'P em I'; A denotação utilizada para
isso é M: A.
Tipos também podem ser usados para melhorar a eficiência da compilação de
termos representando algoritmos funcionais. Se, por exemplo, se sabe que um
subexpressão de um termo é puramente aritmética, então uma avaliação rápida é
possível. Isso ocorre porque a expressão pode ser executado pela ULA da máquina e
não da maneira mais lenta, em que as expressões simbólicas são avaliadas em geral.
Tipos de Dados
Aritmética do cálculo lambda:
Existem várias formas possíveis para definir os números naturais no lambda cálculo,
mas, de longe, os mais comuns são os Church Numerals. Esperamos que uma
linguagem de programação seja capaz de fazer cálculos aritméticos. Os números
podem ser representados no cálculo lambda a partir de zero e escrevendo "suc (zero)"
para representar 1, suc (suc (zero)) para representar 2, e assim em diante. No cálculo
lambda só podemos definir novas funções. Os números serão definidos como funções
usando a abordagem: zero pode ser definido como λs.(λz.z), ou λsz.z resumidamente;
Esta é uma função de dois argumentos s e z. Entende-se aqui que s é o primeiroargumento a ser substituído durante a avaliação e z o segundo. Usando esta notação,
os primeiros números naturais podem ser definidos como:
1 ≡ λsz.s(z)
2 ≡ λsz.s(s(z))
3 ≡ λsz.s(s(s(z)))
e assim por diante.
A função sucessora seria definida como:
S ≡ λwyx.y(wyx). Aplicando essa função na representação da expressão zero,
teriamos: S0 ≡ λyx.y((λsz.z)yx) = λyx.y((λz.z)x) = λyx.y(x) ≡ 1, e assim por diante,
por exemplo, aplicando na representação da expressão um, teriamos S1 ≡
(λwyx.y(wyx))(λsz.s(z)) = λyx.y((λsz.s(z))yx) = λyx.y(y(x)) ≡ 2.
Operações Lógicos:
É possível definir operações lógicas usando uma representação da tabela verdade.
A função AND de dois argumentos pode ser definida como:
 ≡ λxy.xy (λuv.v) ≡ λxy.xyF∧
A função OR de dois argumentos pode ser definida como:
 ≡ λxy.x (λuv.u) y ≡ λxy.xTy∨
A negação de um argumento pode ser definida como:
Λ λx.x (λuv.v) (λab.a) ≡ λx.xFT
A função de negação aplicada a “verdadeiro” é:
¬T ≡ λx.x (λuv.v) (λab.a) (λcd.c)
Que se reduz a:
TFT ≡ (λcd.c) (λuv.v) (λab.a) = (λuv.v) ≡ F,
isto é, o valor “falso”.
Pairs:
Um par (2-tupla) pode ser definido por True e False,usando o “Church encoding for
pairs”. Por exemplo, Pair encapsula o par (x,y), First retorna o primeiro elemento do
par, e Second retorna o segundo.
PAIR := λx.λy.λf.f x y 
FIRST := λp.p TRUE
SECOND := λp.p FALSE
NIL := λx.TRUE
NULL := λp.p (λx.λy.FALSE)
Uma lista ligada pode ser definida como qualquer NIL para a lista vazia,ou PAIR de
um elemento e uma lista menor. O predicado NULL testa se o valor é NIL.
Recursão
As funções recursivas podem ser definidas no cálculo lambda usando uma
função que chama uma função y e depois se regenera. Isto pode ser melhor
compreendido considerando a seguinte função Y:
Y ≡ (λy.(λx.y(xx))(λx.y(xx))) 
Esta função aplicada a uma função R produz:
YR = (λx.R(xx))(λx.R(xx)) ,
que produziu utilizando redução:
R((λx.R(xx))(λx.R(xx)))) ,
significando que YR = R (YR), ou seja, a função R é avaliada usando a chamada
recursiva YR como o primeiro argumento.
O cálculo lambda suporta a representação de recursividade sem maiores
extensões através da utilização de alguns pequenos truques. Assumindo, por exemplo,
uma função fatorial definida por:
FAC = (ln.IF (= n 0) 1 (* n (FAC (- n 1)))) 
Na expressão lambda que representa esta função, um parâmetro será presumido
para receber em si a expressão lambda como o seu valor, de modo que é chamando –
aplicando-o a um argumento – será equivalente a recursão. Assim, para alcançar a
recursividade, o argumento destinado-como-auto-referência (chamado r aqui) sempre
deve ser passada para si mesmo dentro do corpo da função, em um ponto de
chamada: 
G := λr. λn.(1, se n = 0; então n × (r r (n−1)))
com  r r x = F x = G r x  para manter, assim r = G  e
F := G G = (λx.x x) G.
Esta definição baseia-se na capacidade de se dar um nome a uma abstração
lambda e de fazer referência à ela dentro dela mesma. Nenhuma construção deste tipo
é provida pelo cálculo lambda. O cálculo lambda reescreve cada chamada
recursiva..Aplicando uma abstração- β sobre FAC, usada de modo inverso, pode-se
transformar esta definição em: 
FAC = (lfac.(ln. (...fac...)))FAC , que pode ser escrita como:
FAC = H FAC, onde:
H = (lfac.(ln. (...fac…))).
A definição de H é trivial. É uma abstração lambda ordinária e não usa
recursão, sendo uma equação matemática.Por exemplo, para resolver a equação
matemática: x^2 - 2 = x , procuramos por valores de x que satisfazem a equação. De
forma similar, busca-se uma expressão lambda para FAC que satisfaça FAC = H
FAC.A equação FAC = H FAC postula que, quando a função H é aplicada a FAC, o
resultado é FAC. Diz-se então que FAC é um ponto fixo de H. Uma função pode ter
mais de um ponto fixo. Por exemplo, na função abaixo, tanto 0 quanto 1 são pontos
fixos da função: λy. * y y a qual calcula o quadrado de seu argumento.
Em resumo, estamos procurando por um ponto fixo para H. Claramente isto
depende somente de H. Para isto, invente-se, a título provisório, uma função Y, a qual
toma uma função como argumento e devolve o seu ponto fixo como resultado. 
Assim Y tem o comportamento de: Y H = H (Y H) e e Y é chamado de combinador
de ponto fixo. Assim, caso possamos produzir um Y, temos uma solução para o
problema da recursividade. 
Para a transformação de uma expressão recursiva em uma não-recursiva,
utilizamos o combinador de ponto fixo, uma função que chamamos de Y.A
propriedade que Y necessita ter é: Y H = H (Y H) e isto representa evidentemente a
recursão da forma mais pura, uma vez que esta fórmula pode ser utilizada para
representar, de forma abstrata, qualquer fórmula recursiva que queiramos. O truque é
que podemos representar Y como uma abstração lambda sem utilizar a recursão: 
Y = (λh. (λx.h (x x)) (λx. h (x x))) .
Para demonstrar que Y possui a qualidade desejada, evaluemos: 
Y H 
= (λh. (λx.h (x x)) (λx. h (x x))) H
<-> (λx.H (x x)) (λx. H (x x)) 
<-> H ((λx.H (x x)) (λx. H (x x))) 
<-> H (Y H) 
O fato de Y poder ser definido como uma abstração lambda é, do ponto de vista
matemático, realmente digno de nota. Do ponto de vista da implementação, é
relativamente ineficiente implementar Y como uma abstração lambda. Para a
construção de linguagens funcionais, utiliza-se geralmente uma função embutida com
a regra de redução: Y H -> H (Y H).
Conclusão
O cálculo lambda foi discutido largamente. Vimos principalmente o cálculo lambda 
não tipado, que é a parte mais relevante para a ciência da computação. O cálculo 
lambda tipado foi discutido brevemente. O cálculo lambda tem um grande papel no 
desenvolvimento da teoria de linguagens de programação, especialmente nas 
linguagens funcionais, em particular Lisp, mas também em outras linguagens 
funcionais, como Haskell e Miranda.
Referências
MICHAELSON, G..An Introduction to Functional Programming through Lambda
Calculus. Addison-Wesley: 1989. 
JONES, N.D.. Computability and Complexity: From a Programming Perspective.
MIT Press: 1997. 
BARENDREGT, H.P.. The Lambda Calculus: Its Syntax and Semantics. North-
Holland, revised edition: 1984. 
KRIVINE, J.L.. Lambda-Calculus, Types and Models. Masson: 1993.
REVESZ, G.. Lambda-Calculus Combinators and Functional Programming,
Cambridge University Press, Cambridge: 1988, chapters 1–3. 
HINDLEY, J.R ; SELDIN, J.P.. Introduction to Combinators and λ-Calculus.
Cambridge University Press: 1986. 
KOGGE,P. M.. The Architecture of Symbolic Computers, McGraw-Hill, New York:
1991, chapter 4.

Outros materiais