La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Compilación de Lenguajes Funcionales Perezosos

Presentaciones similares


Presentación del tema: "Compilación de Lenguajes Funcionales Perezosos"— Transcripción de la presentación:

1 Compilación de Lenguajes Funcionales Perezosos
Gustavo Betarte

2 Contenido del curso Introducción: LF puros y perezosos. Programación monádica Parsing: Combinadores de parsing. La mónada Parser. Chequeo de tipos: Hindley-Milner. Algoritmo de inferencia. Reducción de grafos: Evaluación perezosa de expresiones funcionales. Estudio de un intérprete. Compilación de pattern-matching y lambda lifting. La máquina G: Máquina abstracta y su modelo computacional. Compilación y ejecución de supercombinadores. Esquemas de compilación. Las máquinas TIM y Spineless Tagless G. Recolección de residuos (garbage collectors).

3 Evolución de Lenguajes de Programación Funcionales
Cálculo Lambda Lenguajes de programación: Lisp, Iswim, ML, Haskell Características principales de LPF: Funciones de alto orden Evaluación perezosa Abstracción de datos Ecuaciones y pattern-matching

4 Cálculo Lambda Un cálculo que captura el aspecto computacional de la noción de función (Church [ , 1940]) Los lenguajes funcionales modernos pueden ser entendidos como un embellecimiento sintáctico de l. Def 1. Expresiones de l (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)

5 Cálculo Lambda (2) Def. 4 Sustitución 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) e ® e1[x := e1] (b) (\x.e x) ® e si x Ï FV(e) (h) Def. 6 Cualquier expresión de la forma (\x.e1) e2 es llamado un b-redex

6 Cálculo Lambda (3) Def. 7 e1 ®* e2 significa que e2 puede ser obtenido a partir de e1 mediante una secuencia finita (posiblemente vacía) de pasos de reducción usando ® (clausura reflexo-transitiva). Def. 8 La expresión 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, ® b es confluente. Teorema. Si ® es confluente entonces para toda expresión e su forma normal, si existe, es única.

7 Cálculo Lambda (4) Estrategias de reducción.
Reglas de computación para seleccionar pasos de reducción . Leftmost-Outermost (Normal order): El redex seleccionado en cada paso de reducción es aquel que comienza más a la izquierda en la expresión. (argumento no necesariamente en forma normal) Leftmost-Innermost (Applicative order): El redex seleccionado en cada paso de reducción es aquel que termina más a la izquierda en la expresión. (la abstracción y argumento ya estarán en forma normal cuando se selecciona el redex). Call-by-Name: LO pero no se reduce en el cuerpo de una abstracción. Call-by-Value: LI pero no se reduce en el cuerpo de una abstracción.

8 Cálculo Lambda (5) Teorema del punto fijo.
Toda expresión 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 función recursiva puede ser escrita sin usar recursión: 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 cálculo lambda. Kleene[1936]: l-definibilidad equivalente a recursividad (Gödel y Herbrand) Turing[1937]: Turing-computabilidad equivalente a l-definibilidad.

9 LISP Un lenguaje algebraico para el procesamiento de listas
McCarthy[1960, 1963] Contribuciones: La expresión condicional y su uso en recursión 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.

10 Cálculo 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: Codificación en l Nociones primitivas: semántica usando d-reducción e := x | c | e1 e2 | \x.e If True e1 e2 => e1 If False e1 e2 => e2 extensión conservativa: e1 ¹ e2 en l entonces e1 ¹ e2 en l d

11 Iswim Mecanización de evaluación de expresiones usando una máquina abstracta. (SECD, P. Landin[1964]). Subset de ALGOL 60 definido en l . Innovaciones Sintácticas Notación infija Expresiones let y where: definiciones mutuas y recursivas Uso de layout Semánticas Enfasis en generalidad: lenguaje rico sintácticamente en función de un lenguaje pequeño y muy expresivo. Enfasis en razonamiento ecuacional. SECD como simple máquina abstracta en la cual se ejecutan expresiones funcionales.

12 Iswim (2) l 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 contraposición a cómo se calcula estilo declarativo de programación es mejor que el imperativo

13 Características principales de lenguajes funcionales modernos
Funciones de alto orden Evaluación perezosa Ecuaciones y pattern-matching Abstracción de datos

14 Funciones de alto orden
Funciones son consideradas ¨first-class values¨: abstracción sobre un mecanismo de abstracción. add2 = twice succ add2 = twice (\x -> x + 1) where twice = f . f where twice = f . f succ x = x + 1 Alto orden como un mecanismo de modularización (Hughes[1984]) sum [] = prod [] = 1 sum (x:xs) = add x (sum xs) prod(x:xs) = mul x (prod xs) abstracción: 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

15 Evaluación perezosa Reglas de reducción con orden normal son las más seguras, en el sentido de que garantizan la producción de forma normal (si existe) Permite emular recursión usando Y Implementación ingenua puede ser muy ineficiente (\x. (+ x x)) (* 5 4) => (+ (* 5 4) (* 5 4)) => (+ 20 (* 5 4)) => ( ) => 40 La expresión (* 5 4) es calculada tantas veces como ocurrencias de x. Call-by- value: (\x. (+ x x)) (* 5 4) => (\x. (+ x x)) 20) => ( ) => 40 El argumento es evaluado antes que la -reducción se efectúe. Desventajas: Puede evaluar innecesariamente (Ej. (\x.\y.x) 5 ((\x.x x) (\x.x x))) Exige reducción especial para implementar recursión Lisp, Hope, ML aprovechan tecnología en compiladore para leng. imperativos

16 Evaluación perezosa (2)
Cuál es el verdadero problema? Reducción en l es orientada a strings, entonces naturalmente imposibilita una noción de sharing. Alternativa: reducción de grafos (Wadsworth, PhD tesis [1971]) (\x.(+ x x)) (* 5 4) => (+ • •) => (+ • •) => 40 (* 5 4) Evaluación perezosa (call-by-need) : Orden normal de reducción + sharing Argumentos de funciones son evaluados a lo sumo una vez

17 Evaluación Perezosa (3)
Por qué evaluación perezosa? Libera al programador de problemas concernientes al orden de evaluación. Provee la posibilidad de computar usando estructuras de datos infinitas (Turner[1981,1982], Hughes[1984]). Separación 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 computación de la lista será determinado por el contexto. Al no tener control operacional puede ser compuesta con otras funciones modularmente

18 Abstracción 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) Abreviación (sinónimos) type Intree = Tree Int type Flattener = Intree -> [Int]

19 Abstracción 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 declaración 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

20 Ecuaciones y pattern-matching
Uso de razonamiento ecuacional en el diseño y construcción de programas. La ausencia de efectos laterales permite el uso de r. e. Sintaxis también puede ayudar: escribir la definición de una función como una secuencia de ecuaciones.

21 Pattern-matching pat1 => e1
case e of pat1 => e1 pat2 => e si la estructura de e concuerda con pati entonces evaluar ei ... patn => en f pat1 = e f = \x. case x of f pat2 = e2 ===> pat1 => e1 f patn = en patn => en

22 Pattern-matching (2) Ejemplos: 1) fac 0 = 1 2) fac 0 = 1
fac n = n * fac (n - 1) fac n | n>0 = n * fac (n-1) 3) length [] = 0 length (x:xs) = 1 + length xs 4) data Tree a = Leaf a | Branch (Tree a) (Tree a) fringe (Leaf x) = [x] fringe (Branch left right) = fringe left ++ fringe right

23 Pattern-matching (3) Linealidad de parámetros formales Problemas:
member x [] = False member x (x:xs) = True member x (y:xs) = member x xs Problemas: alleq [x,x,x] = True alleq y = False alleq [1,2,bot] ? Evaluación de parametros de izquierda a derecha ==> False En el caso derecha a izquierda => el programa diverge. En Haskell: No se permiten parámetros repetidos: Ecuaciones lineales

24 Pattern-matching (4) Conexión de ecuaciones
fac 0 = top-to-bottom (Haskell, ML, etc.) fac n = n * fac (n-1) Cómo garantizar que las ecuaciones son disjuntas? Motivación: el orden se vuelve irrelevante y se puede razonar sobre la aplicación de una ecuación independientemente del resto . Para ecuaciones sin guardas la propiedad de ser disjuntas se puede verificar estáticamente. Pero, ecuaciones con guardas tornan el problema indecidible (equivale a determinar la igualdad de dos predicados recursivos).

25 Pattern-matching (5) Orden de evaluación de argumentos.
f 1 1 = g 1 1 = f 2 bot? f 2 x = g x 2 = g bot 2? Puede un compilador determinar siempre en qué orden evaluar argumentos? Ejemplo (Berry[1978]) f 0 1 x = 1 f 1 x 0 = Disjuntas, pero... f x 0 1 = 3 f 0 1 bot (= 1?) f 1 bot 0 (= 2?) f bot 0 1 (= 3?) En Haskell: evaluación de izquierda a derecha


Descargar ppt "Compilación de Lenguajes Funcionales Perezosos"

Presentaciones similares


Anuncios Google