You are on page 1of 25

Compilacin de Lenguajes

Funcionales Perezosos
Gustavo Betarte

Contenido del curso


Introduccin: LF puros y perezosos. Programacin mondica
Parsing: Combinadores de parsing. La mnada Parser.
Chequeo de tipos: Hindley-Milner. Algoritmo de inferencia.
Reduccin de grafos:
Evaluacin perezosa de expresiones funcionales.
Estudio de un intrprete.
Compilacin de pattern-matching y lambda lifting.
La mquina G:
Mquina abstracta y su modelo computacional.
Compilacin y ejecucin de supercombinadores.
Esquemas de compilacin.
Las mquinas TIM y Spineless Tagless G.
Recoleccin de residuos (garbage collectors).

Evolucin de Lenguajes de
Programacin Funcionales
Clculo Lambda
Lenguajes de programacin: Lisp, Iswim, ML, Haskell
Caractersticas principales de LPF:
Funciones de alto orden
Evaluacin perezosa
Abstraccin de datos
Ecuaciones y pattern-matching

Clculo Lambda
Un clculo que captura el aspecto computacional de la nocin de
funcin (Church [1932-1933, 1940])
Los lenguajes funcionales modernos pueden ser entendidos como un
embellecimiento sintctico de
Def 1. xpresiones de (puro y no tipado)
e := x | \x.e | e e
Def 2. Variables libres
FV(x) = {x}, FV(e e) = FV(e) U FV(e), FV(\x.e) = FV(e) - {x}
Def 3. Variables ligadas
BV(x) = {}, BV(e e) = BV(e) U BV(e), BV(\x.e) = {x} U BV(e)

Clculo Lambda (2)


Def. 4 Sustitucin
x[z := e] = e
si x z
=x
si x z
(e e)[z := e] = (e [z := e]) (e[z := e])
(\x.e1)[x := e] = \x.e1
(\x.e1)[z := e] = \x.e1[z := e]
si x z y x e
= \y.((e1[x := y]) [z := e]) si x z , x FV(e) e y FV(e1 e)
Def. 5 Reducciones Beta y Eta
(\x.e1) e2
\x.e x)

e1[x := e1]
e si x FV(e)

(
(

Def. 6 Cualquier expresin de la forma (\x.e1) e2 es llamado un -redex

Clculo Lambda (3)


Def. 7 e1 e2 significa que e2 puede ser obtenido a partir de e1
mediante una secuencia finita (posiblemente vaca) de pasos de
reduccin usando clausura reflexo-transitiva).
Def. 8 La expresin e est en forma normal (respecto a si
e e implica que e = e.
Def. 9 Se dice que es confluente (o es Church-Rosser) si:
para todo e, e1, e2 tal que e e1 y e e2 entonces existe e3 tal
que e1 e3 y e2 e3. En particular, es confluente
Teorema. Si es confluente entonces para toda expresin e su
forma normal, si existe, es nica.
6

Clculo Lambda (4)


Estrategias de reduccin.
Reglas de computacin para seleccionar pasos de reduccin .
Leftmost-Outermost (Normal order): El redex seleccionado en cada paso de
reduccin es aquel que comienza ms a la izquierda en la expresin. (argumento
no necesariamente en forma normal)
Leftmost-Innermost (Applicative order): El redex seleccionado en cada paso de
reduccin es aquel que termina ms a la izquierda en la expresin. (la
abstraccin y argumento ya estarn en forma normal cuando se selecciona el
redex).
Call-by-Name: LO pero no se reduce en el cuerpo de una abstraccin.
Call-by-Value: LI pero no se reduce en el cuerpo de una abstraccin.

Clculo Lambda (5)


Teorema del punto fijo.
Toda expresin lambda e tiene un punto fijo e tal que (e e) = e.
Y = \f.(\x.f (x x)) (\x.f (x x)) (paradoxical combinator).
(Y e) = e (Y e)
Toda funcin recursiva puede ser escrita sin usar recursin:
fac = Y (\fac.\n.if (n = 0) then 1 else (n * (fac (n - 1)))
Tesis de Church.
Las funciones de N en N efectivamente computables son aquellas definibles en
el clculo lambda.
Kleene[1936]: -definibilidad equivalente a recursividad (Gdel y Herbrand)
8
Turing[1937]: Turing-computabilidad equivalente a -definibilidad.

LISP
Un lenguaje algebraico para el procesamiento de listas
McCarthy[1960, 1963]
Contribuciones:
La expresin condicional y su uso en recursin
El uso de listas y funciones de alto orden sobre ellas
El uso de garbage collecting.
El uso de S-expressions para representar programas y datos.

Clculo Lambda con constantes


True = \x.\y.x
False = \x.\y.y
cond = \p.\c.\a.p c a

(cond p c a = if p then c else a)

(= n n) => True
(= n m) => False
Que pasa con +, *, 0, 1?
Alternativas:
Codificacin en
Nociones primitivas: semntica usando -reduccin
e := x | c | e1 e2 | \x.e
If True e1 e2 => e1 If False e1 e2 => e2
extensin conservativa: e1 e2 en entonces e1 e2 en

10

Iswim
Mecanizacin de evaluacin de expresiones usando una mquina abstracta.
(SECD, P. Landin[1964]). Subset de ALGOL 60 definido en
Innovaciones
Sintcticas
Notacin infija
Expresiones let y where: definiciones mutuas y recursivas
Uso de layout
Semnticas
Enfasis en generalidad: lenguaje rico sintcticamente en funcin de un lenguaje
pequeo y muy expresivo.
Enfasis en razonamiento ecuacional.
SECD como simple mquina abstracta en la cual se ejecutan expresiones
funcionales.
11

Iswim (2)
extendido con constantes y expresiones let y where .
e := ... | e where d1 ... dn | let d1 ... dn in e
d := x = e | x x1 ... xn = e
let d1 ... dn in e => e where d1 ... dn
x x1 ... xn = e => x = \x1.\x2 ...\xn.e
e where x1 = e1 => (\x1.e) (Y \x1.e1)
e where (x1 = e1) (x2 = e2) ... (xn = en)
=> (\x1.e) (Y \x1.e1)
where x2 = (\x1.e2) (Y \x1.e1)
...
xn = (\x1.en) (Y \x1.e1)
Landin y LF modernos:
qu es el resultado en contraposicin a cmo se calcula
estilo declarativo de programacin es mejor que el imperativo

12

Caractersticas principales de
lenguajes funcionales modernos
Funciones de alto orden
Evaluacin perezosa
Ecuaciones y pattern-matching
Abstraccin de datos
13

Funciones de alto orden


Funciones son consideradas first-class values: abstraccin sobre
un mecanismo de abstraccin.
add2 = twice succ
where twice = f . f
succ x = x + 1

add2 = twice (\x -> x + 1)


where twice = f . f

Alto orden como un mecanismo de modularizacin (Hughes[1984])


sum [] = 0
sum (x:xs) = add x (sum xs)

prod [] = 1
prod(x:xs) = mul x (prod xs)

abstraccin: add/mul como f, 0/1 como init, sum/prod como fold f init, donde
(fold f init) [] = init
(fold f init) (x:xs) = f x ((fold f init) xs)
sum = fold add 0

prod = fold mul 1

14

Evaluacin perezosa
Reglas de reduccin con orden normal son las ms seguras, en el
sentido de que garantizan la produccin de forma normal (si existe)
Permite emular recursin usando Y
Implementacin ingenua puede ser muy ineficiente
(\x. (+ x x)) (* 5 4) => (+ (* 5 4) (* 5 4)) => (+ 20 (* 5 4)) => (+ 20 20) => 40
La expresin (* 5 4) es calculada tantas veces como ocurrencias de x.
Call-by- value: (\x. (+ x x)) (* 5 4) => (\x. (+ x x)) 20) => (+ 20 20) => 40
El argumento es evaluado antes que la -reduccin se efecte.
Desventajas:
Puede evaluar innecesariamente (Ej. (\x.\y.x) 5 ((\x.x x) (\x.x x)))
Exige reduccin especial para implementar recursin

15

Lisp, Hope, ML aprovechan tecnologa en compiladore para leng. imperativos

Evaluacin perezosa (2)


Cul es el verdadero problema?
Reduccin en es orientada a strings, entonces naturalmente
imposibilita una nocin de sharing.
Alternativa: reduccin de grafos (Wadsworth, PhD tesis [1971])
(\x.(+ x x)) (* 5 4) => (+ ) => (+ ) => 40
(* 5 4)

20

Evaluacin perezosa (call-by-need) :


Orden normal de reduccin + sharing
Argumentos de funciones son evaluados a lo sumo una vez

16

Evaluacin Perezosa (3)


Por qu evaluacin perezosa?
Libera al programador de problemas concernientes al orden de
evaluacin.
Provee la posibilidad de computar usando estructuras de datos
infinitas (Turner[1981,1982], Hughes[1984]).
Separacin de datos del control.
nats = 0 : map succ nats
filter p [] = []
filter p (x:xs) = if (p x) then (x:rest) else filter p xs
filter p nats puede ser escrito sabiendo que el grado de computacin de la lista

ser determinado por el contexto. Al no tener control operacional puede ser


compuesta con otras funciones modularmente

17

Abstraccin de datos
Tipos algebraicos de datos (o concretos)
data List a = Nil | Cons a (List a)
data Tree b = Empty | Node b (List (Tree b))
List, Tree: constructores de tipos ( List :: Type -> Type)
Nil, Cons, Empty, Node: constructores de datos (o simplemente constructores)

Abreviacin (sinnimos)
type Intree =
type Flattener

Tree Int
= Intree

->

[Int]

18

Abstraccin de datos (2)


Tipos abstractos de datos
En ML:
abstype Queue a = Q [a]
where first (Q as) = last as
isempty (Q []) = True
isempty (Q as) = False

...
first, isempty, ... son visibles en el scope de la declaracin de Queue, pero el
constructor Q y su tipo no lo son.
En Haskell:
module Queue (Queue, first, isempty) where
data Queue a = Q [a]
first (Q as) = last as
isempty (Q []) = True
isempty (Q as) = False

...

19

Ecuaciones y pattern-matching
Uso de razonamiento ecuacional en el diseo y construccin de
programas.
La ausencia de efectos laterales permite el uso de r. e.
Sintaxis tambin puede ayudar: escribir la definicin de una
funcin como una secuencia de ecuaciones.

20

Pattern-matching
case e of
pat1 => e1
pat2 => e2

si la estructura de e concuerda con pati entonces evaluar ei

...
patn => en

pat1 = e1

pat2 = e2
...
patn = en

f
===>

\x. case x of
pat1 => e1
...
patn => en

21

Pattern-matching (2)
Ejemplos:
1) fac 0

= 1
fac n = n * fac (n - 1)

3) length []

= 0
= 1 + length xs

length (x:xs)

4) data Tree a

2) fac 0
= 1
fac n | n>0 = n * fac (n-1)

Leaf a |

fringe (Leaf x)
fringe (Branch left right)

Branch (Tree a) (Tree a)


=
=

[x]
fringe left ++ fringe right

22

Pattern-matching (3)
Linealidad de parmetros formales
member x []
member x (x:xs)
member x (y:xs)

=
=
=

False
True
member x xs

Problemas:
alleq [x,x,x]
alleq y

True
= False

alleq [1,2,bot] ?

Evaluacin de parametros de izquierda a derecha ==> False


En el caso derecha a izquierda => el programa diverge.
En Haskell: No se permiten parmetros repetidos: Ecuaciones lineales

23

Pattern-matching (4)
Conexin de ecuaciones
fac
fac

0
n

= 1
= n * fac (n-1)

top-to-bottom (Haskell, ML, etc.)

Cmo garantizar que las ecuaciones son disjuntas?


Motivacin: el orden se vuelve irrelevante y se puede razonar sobre la aplicacin
de una ecuacin independientemente del resto .
Para ecuaciones sin guardas la propiedad de ser disjuntas se puede verificar
estticamente.
Pero, ecuaciones con guardas tornan el problema indecidible (equivale a
determinar la igualdad de dos predicados recursivos).

24

Pattern-matching (5)
Orden de evaluacin de argumentos.
f 1 1 = 1
f 2 x = 2

g 1 1
g x 2

= 1
= 2

f 2 bot?
g bot 2?

Puede un compilador determinar siempre en qu orden evaluar argumentos?


Ejemplo (Berry[1978])
f 0 1 x
f 1 x 0
f x 0 1

=
=
=

1
2
3

f 0 1 bot (= 1?)
3?)

Disjuntas, pero...
f 1 bot 0 (= 2?)

bot 0 1 (=

En Haskell: evaluacin de izquierda a derecha

25

You might also like