• Nenhum resultado encontrado

Minicurso 1 Uma introdução ao cálculo lambda e a linguagens de programação funcionais

N/A
N/A
Protected

Academic year: 2021

Share "Minicurso 1 Uma introdução ao cálculo lambda e a linguagens de programação funcionais"

Copied!
68
0
0

Texto

(1)

Minicurso 1

Uma introdução ao cálculo lambda e a

linguagens de programação funcionais

Rodrigo Machado

(2)

Conteúdo

Ideias iniciais Cálculo lambda Sintaxe Operação de substituição Equivalência alfa Redução beta

Propriedades da redução beta

Programação em cálculo lambda

Booleanos Números naturais Pares ordenados Listas Definições locais Funções recursivas Funcões de alta ordem

Revisão Referências

(3)

Conteúdo

Ideias iniciais Cálculo lambda Sintaxe Operação de substituição Equivalência alfa Redução beta

Propriedades da redução beta Programação em cálculo lambda

Booleanos Números naturais Pares ordenados Listas Definições locais Funções recursivas Funcões de alta ordem Revisão

(4)

Antes de iniciarmos …

Considere os seguintes grupos de linguagens de programação: Grupo 1 : OCAML, F#, LISP, Scheme/Racket, Haskell

Grupo 2 : Javascript, Python, Ruby, C#

Grupo 3 : C, C++, Java, Pascal/Delphi

Quais grupos contém linguagens de programação nas quais vocês já programaram?

Você já ouviu falar antes de Máquinas de Turing, Funções Recursivas Parciais ou Cálculo Lambda?

(5)

Antes de iniciarmos (2) …

Suponha uma linguagem de programação com números e valores booleanos. Considere as seguintes construções:

1. execução condicional (if-then e if-then-else)

2. laços de repetição (while e for)

3. definição de variáveis e operador de atribuição

4. definição e aplicação de funções

Se fosse lhe pedido para você escolher três itens acima e jogar fora o item restante, quais itens seriam escolhidos?

Seria possível escrever todos os programas desejados somente com os itens escolhidos?

(6)

Origem: notação lambda

Considere a seguinte definição matemática:

f(x) =x2+ 7

A igualdade acima está definindo uma função f, que consome um número e devolve um número.

f(3) = 32+ 7 = 16

A igualdade acima está aplicando a definição def a um valor específico. O propósito original da notação lambda foi resolver a seguinte

ambiguidade:

f(e) =e2+ 7

Afinal, se trata da aplicação def sobre a constantee= 2.716 . . . ou da

(7)

Origem: notação lambda (2)

A notação lambda (Church, 1932) permite diferenciar claramente a

definição de uma função de sua respectiva aplicação. f=λx.x2+ 7

Acima temos a definição da função. O λxindica quexdeve ser interpretado como um parâmetro formal, isto é, um nome temporário para o valor a ser recebido pela função.

f(3) = (λx.x2+ 7)(3) = 32+ 7

Acima temos a aplicação da funçãof, definida anteriormente, ao valor 3. Note que o significado da aplicação é a substituição do parâmetro

(8)

Origem: cálculo lambda

Ao formalizar as ideias fundamentais de definição e aplicação de funções, se chegou ao cálculo lambda. A versão pura do cálculo não continha nada além de funções (sem números, sem operações).

Ainda na década de 1930, Church e seus alunos (Kleene, Rosser) mostraram que a versão pura do cálculo era tão expressiva quanto outros modelos de computação propostos (em particular, Máquinas de Turing e Funções Recursivas Parciais).

Atualmente, Cálculo Lambda diz respeito a uma grande família de formalismos construídos sobre os mesmos conceitos fundamentais.

(9)

Motivação: por que cálculo lambda?

O cálculo lambda original tem aproximadamente 80 anos! Não existiam nem

computadores naquela época! Por que estudar algo tão antigo em 2013?

Algumas razões:

cálculo lambda foi e continua sendo influente: ele serviu de inspiração para

linguagens de programação como (Lisp e Haskell) e para o estilo de programação funcional nas demais linguagens.

cálculo lambda (com tipos) é a base para o estudo formal de linguagens de

programação e sistemas de tipos (mesmo as orientadas a objetos e imperativas).

cálculo lambda (com tipos) possui uma conexão importante com Lógica

Matemática, sendo a base de assistentes de prova como Coq e Agda.

cálculo lambda é um cálculo minimalista e elegante.

(10)

Motivação: funções anônimas hoje em dia

Linguagens de programação e suporte a funções anônimas:

C : não

Pascal : não

C++ : sim (a partir da versão C++11) Javascript : sim

Python : sim Ruby : sim

C# : sim (a partir de versão 3.0) Java : sim (a partir de versão 8)

E é claro, todas as linguagens de programação funcionais/mistas: LISP, Scheme, Clojure, Scala, Ocaml, F#, Haskell, ...

(11)

Este minicurso

Objetivos

1. Apresentar as ideias fundamentais de cálculo lambda: termos-lambda, substituição, alfa-equivalência, redução beta

2. Argumentar sobre propriedades do cálculo: confluência de redução beta, universalidade

3. Mostrar como codificar diversos tipos de dados e estruturas de controle como termos-lambda

Abordagem

● conceitual (alguns detalhes formais serão omitidos)

foco em programação: vamos definir a função fatorial em cálculo lambda puro.

(12)

Conteúdo

Ideias iniciais Cálculo lambda Sintaxe Operação de substituição Equivalência alfa Redução beta

Propriedades da redução beta

Programação em cálculo lambda Booleanos Números naturais Pares ordenados Listas Definições locais Funções recursivas Funcões de alta ordem Revisão

(13)

Sintaxe: pré-termos

Começaremos definindo um conjuntoΛ− de pré-termos. Considere um conjunto infinito (mas contável) de nomes (a.k.a parâmetros, identificadores, variáveis) o qual chamaremosVar. Vamos denotar os elementos deVarpor x,y,z, . . .

Definição:o conjuntoΛ− é o menor conjunto tal que:

1. sex∈Varentão x∈Λ− (variáveis)

2. seM∈Λ−e N∈Λ− então@(M,N) ∈Λ− (aplicação)

3. sex∈Vare M∈Λ− entãoλx.M∈Λ− (abstração lambda)

(14)

Sintaxe: exemplos

Exemplos de elementos deΛ−: x x y λx.x λx.y (λx.x) y λx.(x y) (λx.x) (λx.x) λx.λy.x λx.λy.y(λx.y) Nota:precisamos de regras claras para evitar ambiguidade na escrita de um pré-termo.

(15)

Sintaxe: regras de notação

1. O λ engloba tudo à direita (o máximo

possível).

λx.x y=λx.(x y)≠ (λx.x)y

2. O operador @ é associativo à esquerda.

x y z= (x y) z≠x (y z)

3. Notação simplificada para λ’s seguidos.

λx y z.M=λx.λy.λz.M x λy.(λx.x y)(z w) ⇕ .... @. .... .. λy... .. @. .... .. @. .... .. w . .. .. z . .. .. λx... .. @. .... .. y . .. .. x . .. .. x

(16)

Sintaxe: termos com nomes especiais

Alguns pré-termos são famosos e possuem nomes especiais. Combinadores (lógica combinatorial)

I=λx.x K=λx y.x

S=λx y z.(x z(y z))

Auto-aplicação e ponto fixo

ω=λx.x x Ω=ω ω

Y=λf.(λx.f(x x))(λx.f(x x))

(17)

Variáveis livres e ligadas

Definição:dentro do pré-termoλx.M, dizemos queM é o escopo de

λx.

Definição:uma ocorrência dexdentro do escopo deλx é dita ligada. Caso contrário,x ocorre livre.

Exemplo:

a) λx.x y x é ligada, yé livre b) λx.z λz.z x z é livre, ze x são ligadas c) λx.x λx.xy x ex são ligadas,yé livre

Nota:

1. Um mesmo nome por ter ocorrências ligadas e livres no mesmo pré-termo (b).

(18)

Variáveis livres e ligadas (2)

Ocorrências livres e ligadas de variáveis têm significados distintos:

● variáveis livresreferem-se a nomes externos (globais).

● variáveis ligadasreferem-se a parâmetros formais (locais). Nomes de variáveis livres são importantes:

expressões distintas⎧⎪⎪⎨⎪⎪

sin(π) − 42 +π2

sin(e) − 42 +e2

Nomes de parâmetros formais não são importantes: mesma definição⎧⎪⎪⎨⎪⎪

λx. sin(x) − 42 +x2 λe. sin(e) − 42 +e2

(19)

Variáveis livres e ligadas (3)

Definição:a funçãoFVcomputa as variáveis que ocorrem livres em um pré-termo.

FV(x) = {x}

FV(λx.M) = FV(M) − {x} FV(M N) = FV(M) ∪FV(N)

Definição:um pré-termoM onde FV(M) = {} é fechado, também

(20)

Operação de substituição

A operação de substituição

M[x∶=N]

substitui todas as ocorrências livres dexem M porN.

Exemplo: 1) (λx.xy)[x∶=w] = λx.xy 2) (λx.xy)[y∶=w] = λx.xw 3) (λx.xy)[z∶=w] = λx.xy 4) (zλz.z)[z∶=w] = wλz.z 5) (zz)[z∶=λz.zz] = (λz.zz)(λz.zz) 6) (λx.xy)[y∶=x] = (λx.xx)?

(21)

Captura de variáveis livres

Problema do Ex. 6: captura de variáveis livres

M ³¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹µ (λx.xy) [y∶= N © x]

● ConsidereM: na posição onde está y, o nomex é ligado

● ConsidereN: o nome xocorre livre

● Ao substituiry porN, podemos colocar um x livre em uma posição onde o mesmo nome xestá ligado.

● Mas nomes livres e ligados possuem interpretações distintas, e isso

altera o significado do termo.

(22)

Operação de substituição: definição formal

Definição:operação de substituiçãoevitando captura de variáveis livres x[y∶=P] = { P sex=y x caso contrário (λx.M)[y∶=P] = { λx.M sex=y λx.(M[y∶=P]) se x≠ye x∉FV(P) (M N)[y∶=P] = M[y∶=P] N[y∶=P]

Pergunta:segundo esta definição, qual o resultado de(λx.xy)[y∶=x] ? Resposta:indefinido!

(23)

Equivalência alfa

Definição:dois pré-termosM eNsão α-equivalentes (M=αN) sss eles

diferem somente na escolha dos nomes de variáveis ligadas.

Exemplo:

λx.xy=αλz.zy λx.xy≠αλy.yy λx.xx=αλz.zz λy.zy≠αλy.xy

O conceito deα-equivalência captura a intuição que a escolha dos nomes dos parâmetros formais realmente não é importante.

(24)

Equivalência alfa: definição formal

Definição:=α é a menor relação de equivalência sobre Λ− tal que

y∉FV(M) λx.M=αλy.(M[x∶=y]) (α) M=αM′ M N=αM′ N M=αM′ N M=αN M′ M=αM′ λx.M=αλx.M′

(25)

Termos lambda

Definição:um termo lambda é uma classe de equivalência de pré-termosα-equivalentes.

Notação:vamos denotar por {M}α o termo lambda contendo o

pré-termoM.

Exemplo:

{λx.x}α= {λx.x, λy.y, λz.z, . . .}

{λx.x y}α= {λa.a y, λb.b y, . . . } Definição:Λé conjunto de todos os termos lambda:

Λ= Λ−

(26)

Termos lamba: operação de substituição

Operações definidas emΛ− podem ser estendidas para Λ. Lembre: (λx.xy)[y∶=x] ⇒ indefinido Porém, como λx.xy=αλa.ay e (λa.ay)[y∶=x] =λa.ax

podemos estenderM[x∶=N] para termos, obtendo

{λx.xy}α[y∶= {x}α] = {λa.ax}α

Efeito: temos emΛuma operação de substituição que é total e

(27)

Termos vs pré-termos

No que segue, vamos falar de termos e não mais de pré-termos.

Contudo, vamos escrever termos usandoMao invés de{M}α, e assumir

que a operação de substituição é total e evita a captura de variáveis livres.

Essa convenção é também chamada convenção de Barendregt, devido à sua utilização no livro deste autor.

(28)

Redexes e formas normais

Definição:um redex (reducible expression) é um subtermo de Mcom o formato

(λx.P)Q

e o seu respectivo contractum é

P[x∶=Q]

Definição:um termo que não contenha nenhum redex é chamado

forma normal (ou termo irredutível). Exemplo:

a) λy.(λx.y x)((λy.x) y) contém dois redexes b) λx.λy.x x é uma forma normal

(29)

Redução beta

Redução beta descreve a avaliação de termos lambda através de

substituição.

Temos M→βNse obtivermos Natravés da contração de um redex de

M.

Exemplo:

(λz.λx.x z)y →β λx.x y

λy.(λx.y x) ((λy.x) y) →β λy.(λx.y x) x λy.(λx.y x) x →β λy.y x

(30)

Redução beta: definição formal

Definição:→β é a menor relação em Λtal que

(λx.P) Q→βP[x∶=Q] (β) M→βM′ λx.M→β λx.M′ M→βM′ N M→βN M′ M→βM′ M N→βM′ N Definição:↠β é o fecho transitivo e reflexivo de→β.

Intuitivamente,M↠NquandoM reduz paraNem 0 ou mais passos de redução beta.

(31)

Equivalência beta

β-equivalência identifica termos que possuem reescritas confluentes. Definição:=β é a menor relação emΛ tal que

M↠βP N↠βP M=β N

Exemplo:os seguintes termos são β-equivalentes:

M= (λz.λx.x z)y N= (λu.λx.x y) (t t)

P=λx.x y

(32)

Equivalência beta: possuir forma normal

Definição:dizemos que um termoM possui forma normal sss M=β N

eNé uma forma normal.

Exemplo:

(λx.x x) possui forma normal (ele é f.n.)

(λx.x x) apossui forma normal (eleβ-reduz para (a a), que é f.n.) (λx.x x) (λx.x x)não possui forma normal (ele β-reduz para si mesmo)

(33)

Estratégias de avaliação

Um termoPpode ter diversos redexes e, portanto, avaliar para distintos termos. Exemplo:(considere ω=λx.x x e I=λx.x) .. .... @. .... .. @. .... ..I . .. .. ω . .. .. ω .... .... @. .... .. @. .... ..I . .. ..I . .. .. ω . β . .... @. .... .. @. .... ..I . .. .. ω . .. .. @. .... ..I . .. .. ω . β

(34)

Estratégias de avaliação (2)

Definição:Uma estratégia de avaliação é uma escolha fixa para todos os termos de qual redex tem prioridade na redução.

Avaliação preguiçosa (lazy): ● redex mais externo, mais à

esquerda

● realiza a aplicação sem normalizar os argumentos

Avaliação estrita (strict): ● redex mais interno, mais à

esquerda

● normaliza todos os argumentos antes de aplicar a função

Exemplo:

● lazy: (true I Ω) →β (λy.I) Ω →β I

(35)

Propriedades de redução beta: confluência

Confluência: (Church-Rosser)

seN←βM→βN′ então existe Ptal que N↠βP↞β N′

Corolário: formas normais são únicas. Exemplo: ω(II) //  ω(I)  (II)(II) //I(II) //II

(36)

Propriedades de redução beta: normalização

Normalização:

se o termoM possui forma normalN, então avaliarM usando a estratégia preguiçosa certamente alcança N.

● observe que nem todo termo possui forma normal.

● avaliação estrita pode não alcançar forma normal.

● determinar equivalência beta de termos é um problema indecidível.

Nota:não vamos apresentar neste minicurso as provas de confluência e normalização da redução beta. Contudo, elas são essenciais para a utilização do cálculo como linguagem de programação.

(37)

Cálculo lambda: revisão da teoria

Os seguintes conceitos e definições foram apresentados:

● pré-termos(Λ−), variáveis livres e ligadas, operação de substituição,

captura de variáveis livres.

● α-equivalência, termos (Λ), extensão de operações de pré-termos para

termos.

● redexes, formas normais,β-redução,β-equivalência, possuir forma normal, estratégia de avaliação.

● propriedades deβ-redução: confluência, normalização.

Alguns aspectos importantes não foram mencionados (por brevidade):

● provas formais das propriedades de confluência e normalização (β-redução)

● reduçãoη(extensionalidade)

(38)

Conteúdo

Ideias iniciais Cálculo lambda Sintaxe Operação de substituição Equivalência alfa Redução beta

Propriedades da redução beta Programação em cálculo lambda

Booleanos Números naturais Pares ordenados Listas Definições locais Funções recursivas Funcões de alta ordem

Revisão Referências

(39)

Cálculo lambda como linguagem de programação

A linguagem de termos lambda juntamente com a redução beta (e uma estratégia de avaliação fixa) compõe uma linguagem de programação

idealizada.

Podemos enxergar a seguinte associação:

● termo lambda = estado da máquina

● redução beta = passo de execução da máquina

● formas normais = valores finais (parada da máquina)

Ainda em 1936, Church mostrou que todas as funções computáveis podem ser descritas em cálculo lambda. Isso significa que esse modelo de computação é universal.

(40)

Codificações

Como a linguagem lambda pura provê somente variáveis, abstração lambda e aplicação de termos a termos, é necessário codificar em termos lambda

Dados:

● valores booleanos e operações lógicas

● números, operações aritméticas e operações relacionais

● coleções: pares e listas

Estruturas de controle: ● execução condicional

● definições locais

● recursão

(41)

Booleanos

Definição:booleanos de Church:

true=λx y.x false=λx y.y

Intuição

true consome dois termos, e retorna o primeirofalse consome dois termos, e retorna o segundo

(42)

Construção condicional

Definição:construção if-then-else :

ifathen belsec=λa b c .a b c

Ideia: aplicar o booleano resultante do teste sobre os valores a serem

retornados.

Justifica a definição de valores-verdade como seletores.

(43)

Números naturais

Definição:numerais de Church:

0=λf x.x 1=λf x.f x 2=λf x.f (f x) 3=λf x.f (f (f x)) ⋮ n=λf x. n ³¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹µ f (f (f . . .(f x) . . .))

(44)

Operações aritméticas: sucessor

Função sucessor:

succ=λn p q.p (n p q) Ideia da construção:

1. receber um numeral de Church ncom estrutura

n=λf x .f(f. . .(f x) . . .) 2. o resultado deve terpe qligados por lambdas:

λp q. . . .

3. o termo(n p q) muda os f’s emp’s, e ox emq.

(45)

Operações aritméticas e relacionais

Definição:operações aritméticas básicas:

add=λ m n p q.m p(n p q) mult=λ m n p q.m (n p) q

exp=λ m n .n m Definição:teste de zero:

isZero=λn.n (λx.false) true

(46)

Pares ordenados

Definição:um par(M,N) pode ser representado por pairM Nonde

pair=λ m n b .b m n Exemplo:

pair 0 true=λb.b0 true Definição:funções de acesso ao conteúdo de um par

fst=λp.p true snd=λp.p false

(47)

Pares ordenados: predecessor

Usando pares podemos definirpred∶ N → N onde pred(n) =⎧⎪⎪⎨⎪⎪

0 se n≤ 1 n− 1 caso contrário

Função auxiliar: shiftInc(a,b) = (b,b+ 1)

shiftInc=λp.⟨sndp, succ(sndp)⟩ Definição:o termo pred abaixo implementa a funçãopred

(48)

Listas

Listas podem ser consideradas as estruturas de dados fundamentais em linguagens de programação funcionais.

A definição algébrica de uma lista oferece dois construtores:

● empty(lista vazia)

● cons, que recebe um valor e uma lista, e retorna a lista prefixada pelo valor.

Exemplo:

empty

(cons 2 empty)

(49)

Listas (2)

Três funções são definidas para acessar o conteúdo da lista:

● isEmptytesta se a lista é vazia

● head retorna o primeiro elemento da lista

● tail retorna a lista resultante da remoção do primeiro elemento. Aplicar head ou tail sobre empty é um erro.

Exemplo:

isEmpty empty => true isEmpty (cons 2 empty) => false head (cons 2 empty) => 2

tail (cons 3 (cons 2 empty)) => (cons 2 empty) head (tail (cons 3 (cons 2 empty))) => 2

(50)

Listas (3)

A seguinte codificação implementa as operações de listas sobre cálculo lambda.

Definição:construtores de listas:

empty=λx. true cons=λh t. pair h t

Definição:operações de lista:

isEmpty=λl.l (λx λy.false) head= fst

(51)

Definições locais

Programas habitualmente tem o formato

definição 1 definição 2 ...

definição n

programa principal

Em cálculo lambda podemos representar definições locais (não-recursivas) através do seguinte esquema:

(52)

Funções recursivas

Considere o problema de definir um termo para executar iteração (laço for) ou definições recursivas em cálculo lambda (função fatorial, por exemplo).

Assuma que temos na linguagem termos primitivos: booleanos, naturais,

succ, pred, isZero, e if-then-else (sem ser via codificação de Church).

Queremos definir uma funçãoI que recebe

● um númeron ● uma funçãof ● um valor inicialx

para o qual(I n f x) resulta em

n

³¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹·¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹¹µ

(53)

Funções recursivas (2)

Tentativa inicial: I=λ n f x.if(isZeron) thenx else(I (predn) f (f x)) Ideia da construção: ● sen= 0 : retorna x

● sen> 0 : itera (n− 1) vezes a funçãofno argumento(f x)

Problemas:

● não há memória para armazenar a definição deI

● definição circular

(54)

Funções recursivas (3)

Imagine o lado direito da equação como a aplicação de um combinador

Ssobre I.

Nesse caso a equação

I=λ n f x.if (isZeron) then x else(I(predn)f (f x))

se torna

I=S I

onde

S=λ X.λ n f x.if (isZeron) thenx else(X (predn) f (f x)) Nota:veja que a definição deS não é circular!

(55)

Pontos fixos

Definição:o ponto fixo (fixed-point, FP) de uma funçãof∶X→X é um elementox∈X tal que f(x) =x

Exemplo:

1) x↦x2 ∶ N → N FP ={0, 1}

2) x↦ ∣x∣ ∶ Z → Z FP ={0, 1, 2, . . .} 3) x↦ −x ∶ Z → Z FP ={0}

4) x↦x− 1 ∶ Z → Z FP ={}

Estamos interessados em encontrar um ponto fixo paraS∶Λ→Λ.

(56)

Pontos fixos: combinador Y

Chamamos o termo abaixo de combinador Y (ou combinador de ponto fixo)

Y=λf.(λx.f(x x))(λx.f(x x))

Teorema:o combinador Y produz um ponto fixo para seu argumento

Demonstração:

YS →β

(λx.S(x x)) (λx.S(x x)) →β

S(λx.S(x x)) (λx.S(x x)) =β S(YS)

YS=βS(YS) e, portanto, YSé um ponto fixo deS

(57)

Pontos fixos: combinador Y em ação

.... @. .... .. ∎ . .. .. Y β .... @. .... .. λx... .. @. .... .. @. .... .. x . .. .. x . .. .. ∎ . .. .. λx... .. @. .... .. @. .... .. x . .. .. x . .. .. ∎ →β .... @. .... .. @. .... .. λx... .. @. .... .. @. .... .. x . .. .. x . .. .. ∎ . .. .. λx... .. @. .... .. @. .... .. x . .. .. x . .. .. ∎ . .. .. ∎ →β .... @. .... .. @. .... .. @. .... .. λx... .. @. .... .. @. .... .. x . .. .. x . .. .. ∎ . .. .. λx... .. @. .... .. @. .... .. x . .. .. x . .. .. ∎ . .. .. ∎ . .. .. ∎ ↠β .... @. .... .. @. .... .. @. .... .. @. .... .. @. .... .. @. .... .. . . . . .. .. ∎ . .. .. ∎ . .. .. ∎ . .. .. ∎ . .. .. ∎ . .. .. ∎

(58)

Pontos fixos: combinador Y em ação (2)

seS =β .... λ...X .. λ n f x... .. if. .... .. X. .... .. (f x) . .... ..f . .. .. (pred n) . .... .. x . .. .. (isZero n)

(59)

Pontos fixos: combinador Y em ação (3)

então(YS) =β .... λ n f x... .. if. .... .. if. .... .. if. .... .. . . . . .... .. (f (f x)) . .. ..

(isZero (pred (pred n))) . .... .. (f x) . .. .. (isZero (pred n)) . .... .. x . .. .. (isZero n)

(60)

Funções recursivas e operador Y

Usando Y podemos codificar funções como termos nos baseando em suas

definições recursivas.

Definição recursiva:

fact(n) =⎧⎪⎪⎨⎪⎪

1 se n≤ 1

n∗fact(n− 1) caso contrário

Combinador:

F=λM.λn.if(isZero (predn)) then 1

else(multn(M(predn)))

Definição final: fact= YF

Nota:avaliação preguiçosa é requerida (Y diverge quando avaliado estritamente)

(61)

Funções de alta ordem

Em programação funcional, é comum termos funções que processam outras funções junto com os dados.

Funções que consomem ou retornam outras funções são chamadas

funções de alta ordem ou funcionais.

Os três funcionais clássicos em linguagens funcionais são map, filter e fold.

A funçãomapconsome uma função fe uma lista de valores l, e retorna a lista de resultados da aplicação def a cada elemento da listal. map succ (cons 3 (cons 1 empty)) =>

(62)

Funções de alta ordem (2)

A funçãofilterconsome um predicadop (função com retorno booleano) e uma lista de valoresl, e retorna a lista contendo os valores eml que satisfazem o predicado.

filter par (cons 3 (cons 2 (cons 1 empty))) => (cons 2 empty)

A funçãofold consome uma operação bináriaop, um valor inicialinite uma listal, e substitui cons porope empty por initem l, retornando um valor final.

fold + 0 (cons 3 (cons 2 (cons 1 empty))) => (+ 3 (+ 2 (+ 1 0)))

(63)

Universalidade de cálculo lambda

Universalidade

Cálculo-lambda como linguagem de programação é Turing-computável.

Há várias formas de provar isso, mas é fácil perceber que

● Usando duas listas podemos codificar uma fita bidirecional

● Podemos codificar estados e símbolos utilizando números

● Usando listas, pares, podemos codificar uma função de transição de estado

● Procedimentos recursivos pode ser utilizados para implementar consulta à função de transição de estado.

(64)

Conteúdo

Ideias iniciais Cálculo lambda Sintaxe Operação de substituição Equivalência alfa Redução beta

Propriedades da redução beta Programação em cálculo lambda

Booleanos Números naturais Pares ordenados Listas Definições locais Funções recursivas Funcões de alta ordem Revisão

(65)

Revisão

O que vimos:

● os componentes fundamentais da teoria de cálculo lambda.

● como utilizar o cálculo lambda puro como uma linguagem de programação

funcional, utilizando diversos mecanismos de codificação. O que não foi visto:

a teoria de lambda calculi é vasta, e inclui diversas variações importantes com sistemas de tipos associados:

○ cálculo lambda simplesmente tipado

○ cálculo lambda polimórfico

○ cálculo lambda com tipos dependentes

● mesmo a teoria do cálculo lambda sem tipos possui diversos resultados que

(66)

Retomando a pergunta inicial …

Suponha uma linguagem de programação com números e valores booleanos. Considere as seguintes construções:

1. execução condicional (if-then e if-then-else)

2. laços de repetição (while e for)

3. definição de variáveis e operador de atribuição

4. definição e aplicação de funções

Pergunta:se fosse necessário escolher somente um dos itens acima, ainda teríamos uma linguagem de programação expressiva o suficiente?

(67)

Conteúdo

Ideias iniciais Cálculo lambda Sintaxe Operação de substituição Equivalência alfa Redução beta

Propriedades da redução beta Programação em cálculo lambda

Booleanos Números naturais Pares ordenados Listas Definições locais Funções recursivas Funcões de alta ordem Revisão

(68)

Referências

The lambda calculus: its syntax and semantics(Barendregt, 1984) An introduction to functional programming through lambda calculus(Michaelson, 1989)

Lectures on the Curry-Howard isomorphism(Sørensen and Urzyczyn, 2006)

A short introduction to the Lambda Calculus(Jung, 2004)

Disponível online emhttp://www.cs.bham.ac.uk/~axj/pub/

papers/lambda-calculus.pdf

How to Design Programs: An Introduction to Computing and Programming(Felleisen, Findler, Flatt, Krishnamurthi, 2003)

Referências

Documentos relacionados

Como a indústria da carne brasileira pode promover o desenvolvimento da pecuária e aumentar seu já importante papel na economia, sem contribuir para o desmatamento tanto no

• O computador executa programas auxiliares escritos em linguagem de máquina para interpretar cada. comando

Eis, por exemplo, um método para produzir uma lista com um dado nú- mero de elementos, onde cada elemento é produzido mediante uma chamada ao método get (de um objecto do

Os dados indicam uma boa associação entre os valores reais e aqueles obtidos pela análise de segmento, com a vantagem de ter sido gerada rapidamente, sem necessitar uma

Compreender melhor noções de programação básica, de C++, de Cobol, de Java, de TML, de Ajax, de hardware, de Windows e de Linux faz parte para desenvolver qualquer tipo

Apesar de oferecer uma representação mais próxima do que o programador está acostumado a manipular, a linguagem Assembly apresenta certas dificuldades para a realização

As razões são duas: (a)após a primeira guerra mundial, os matemáticos autríacos e alemães, nacionalidade dos matemáticos da Escola Austríaca, foram proibidos de participar

• A alteração entre os modos de operação pode ser feita por uma chave ou pelo próprio software de