La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

1 Compilación de Lenguajes Funcionales Perezosos Gustavo Betarte.

Presentaciones similares


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

1 1 Compilación de Lenguajes Funcionales Perezosos Gustavo Betarte

2 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 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 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 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)

5 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.e 1 )[x := e] = \x.e 1 (\x.e 1 )[z := e] = \x.e 1 [z := e] si x z y x e = \y.((e 1 [x := y]) [z := e]) si x z, x FV(e) e y FV(e1 e) Def. 5 Reducciones Beta y Eta (\x.e 1 ) e 2 e 1 [x := e 1 ] ( \x.e x) e si x FV(e) ( Def. 6 Cualquier expresión de la forma (\x.e 1 ) e 2 es llamado un -redex

6 6 Cálculo Lambda (3) Def. 7 e 1 e 2 significa que e 2 puede ser obtenido a partir de e 1 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, e 1, e 2 tal que e e 1 y e e 2 entonces existe e 3 tal que e 1 e 3 y e 2 e 3. En particular, es confluente Teorema. Si es confluente entonces para toda expresión e su forma normal, si existe, es única.

7 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 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]: -definibilidad equivalente a recursividad (Gödel y Herbrand) Turing[1937]: Turing-computabilidad equivalente a -definibilidad.

9 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 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 Nociones primitivas: semántica usando -reducción e := x | c | e 1 e 2 | \x.e If True e 1 e 2 => e 1 If False e 1 e 2 => e 2 extensión conservativa: e 1 e 2 en entonces e 1 e 2 en

11 11 Iswim Mecanización de evaluación de expresiones usando una máquina abstracta. (SECD, P. Landin[1964]). Subset de ALGOL 60 definido en 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 12 Iswim (2) extendido con constantes y expresiones let y where. e :=... | e where d 1... d n | let d 1... d n in e d := x = e | x x 1... x n = e let d 1... d n in e => e where d 1... d n x x 1... x n = e => x = \x 1.\x 2...\x n.e e where x 1 = e 1 => (\x 1.e) (Y \x 1.e 1 ) e where (x 1 = e 1 ) (x 2 = e 2 )... (x n = e n ) => (\x 1.e) (Y \x 1.e 1 ) where x 2 = (\x 1.e 2 ) (Y \x 1.e 1 )... x n = (\x 1.e n ) (Y \x 1.e 1 ) 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 13 Características principales de lenguajes funcionales modernos Funciones de alto orden Evaluación perezosa Ecuaciones y pattern-matching Abstracción de datos

14 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 [] = 0 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 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 16 Evaluación perezosa (2) Cuál es el verdadero problema? Reducción en 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) 20 Evaluación perezosa (call-by-need) : Orden normal de reducción + sharing Argumentos de funciones son evaluados a lo sumo una vez

17 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 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 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 isempty (Q []) = True isempty (Q as) = False...

20 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 21 Pattern-matching case e of pat 1 => e 1 pat 2 => e 2 si la estructura de e concuerda con pat i entonces evaluar e i... pat n => e n f pat 1 = e 1 f = \x. case x of f pat 2 = e 2 ===> pat 1 => e f pat n = e n pat n => e n

22 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 23 Pattern-matching (3) Linealidad de parámetros formales 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 24 Pattern-matching (4) Conexión de ecuaciones fac 0 = 1 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 25 Pattern-matching (5) Orden de evaluación de argumentos. f 1 1 = 1 g 1 1 = 1 f 2 bot? f 2 x = 2 g x 2 = 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 = 2 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 "1 Compilación de Lenguajes Funcionales Perezosos Gustavo Betarte."

Presentaciones similares


Anuncios Google