Compilación de Lenguajes Funcionales Perezosos

Slides:



Advertisements
Presentaciones similares
Rogelio Dávila Pérez Profesor - Investigador
Advertisements

Algoritmos y Programas
Introducción al Teorema de Gödel Eduardo Alejandro Barrio UBA - CONICET 2do Cuatrimestre de 2009 Eduardo Alejandro Barrio UBA.
La aritmetización de la sintaxis
INTELIGENCIA ARTIFICIAL
CLASE 4 EL ENSAMBLADOR.
UPC Tema: ESPACIO VECTORIAL Rn
DESCRIPCION DE SISTEMAS
PROGRAMACIÓN PARALELA Tema 5: Análisis de algoritmos paralelos
Introducción a los Algoritmos
UNIDAD II: ALGORITMOS Y LENGUAJES
Lenguajes de programación
EL CÁLCULO LAMBDA λ.
TEORÍA DE CONJUNTOS.
INSTITUTO TECNOLOGICO DE MINATITLAN
Interpretando objetos
Ecuaciones y Resolución de Ecuaciones Lineales
Expresiones Racionales
Exponentes Racionales y Radicales
DIAGRAMAS DE FLUJO Y PSEUDOCÓDIGO
Estadística Computacional I
1 Tipos inductivos y Pattern Matching Introducción a tipos inductivos y pattern matching Abstracciones con pattern matching. Traducción a cálculo lambda.
1 Parsing Un parser podría ser definido como un programa que analiza una porción de texto para determinar su estructura lógica: la fase de parsing en un.
Reducción de grafos Qué es reducción normal de grafos? Ejemplo:
Chequeo e inferencia de tipos
1 Agregando primitivas 2 Introducción Ahora presentaremos cómo agregar operaciones primitivas a la máquina G. Entenderemos como operaciones primitivas.
Programación monádica
Combinadores SK.
Tipo de Dato Abstracto Tipos de datos:
UNIVERSIDAD LATINA (UNILA) INTRODUCCION A LA PROGRAMACIÓN
UNIVERSIDAD LATINA (UNILA) IV. IMPLANTACION DE ALGORITMOS.
¿Qué es un conjunto? Un conjunto es una colección de objetos considerada como un todo. Los objetos de un conjunto son llamados elementos o miembros del.
La transformada de Laplace
LENGUAJES Y PARADIGMAS DE PROGRAMACIÓN
El Lenguaje ML Programación Declarativa Avanzada
Tema 3. Optimización de Código
METODOLOGIA DE LA PROGRAMACION
Programación I Teoría VI: Recursividad
Sistemas de Ecuaciones lineales
TRAMPAS EN EL DISEÑO DE LENGUAJES CON RELACIÓN A LOS NOMBRES - REGLAS DE ALCANCE - COMPILACIÓN POR SEPARADO CONTROL DE FLUJO - EVALUACIÓN DE EXPRESIONES.
Estructuras de control
Introducción. Agenda Clase 1 ● Preámbulo histórico. ● Razones de la Diversidad de Lenguajes. ● Razones del Éxito de un Lenguaje. ● Clasificación ● Motivación.
PROGRAMACIÓN LÓGICA.
Un lenguaje funcional avanzado:
Cobol C Pascal Fortran 1. INTRODUCCIÓN SmallTalk Java C++
Representación del conocimiento
Sintaxis.
Estructura de Datos y Algoritmos
Agenda Clase 16 Motivación e Historia de la Programación Funcional y la Programación Lógica. Concepto y Características de la Programación Funcional. Ventajas.
PROGRAMACIÓN PROCEDIMENTAL
Introducción al Análisis Sintáctico
Figure: Algoritmos Conceptos básicos. Programación: 1.Establecer una secuencia de acciones que: puedan ser ejecutadas por el procesador realicen una.
UNIDAD 2. ALGORITMOS Y ESTRUCTURAS DE DATOS.
Semantica.
1 Compilación de Pattern Matching Un ejemplo: zipWith f [] ys = [] zipWith f (x:xs) [] = [] zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys Semántica.
Programación No-Imperativa Modelos: Lenguajes Funcionales y Lógicos.
TPPSFAsistentes para programadores Asistentes de Pruebas para Programadores Cálculo de Construcciones.
1 Samba: Un lenguaje funcional perezoso Presentación del lenguaje: qué es un programa Samba definiciones locales abstracciones lambda Tipos inductivos:
1 Compilación, pereza y expresiones let(rec) 2 Compilando un programa Describiremos un compilador para la máquina minimal usando un conjunto de esquemas.
Agenda Clase 6 Iteradores. Enumeración sin iteradores. Loops lógicos. Recursión vs. Iteración. Recursión de Cola. Orden de Evaluación Normal y Aplicativo.
Lenguajes de Programación
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) TRADUCTORES Y ANALIZADOR LEXICOGRÁFICO.
Metodología de la programación
“PARADIGMAS Y LENGUAJES DE PROGRAMACION”
1 Las máquinas TIM y Spineless-Tagless G. 2 TIM: La máquina de tres instrucciones En principio TIM parece ser una máquina de reducción de grafos muy diferente.
Optimización automática de programas (OAP) Germán Vidal 1 Optimización automática de programas Tema 3: Funciones, tipos y expresiones 3.1. Intérpretes,
PARADIGMA Es un marco de referencia que impone reglas sobre cómo se deben hacer las cosas. CONCEPTO DE PARADIGMA DE PROGRAMACION colección de modelos conceptuales.
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) V. GESTIÓN DE TIPOS Y GENERACIÓN DE CÓDIGOS.
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) IV. IMPLANTACION DE ALGORITMOS.
Departamento de Informática Universidad Técnica Federico Santa María Lenguajes Funcionales Francisco Bórquez Departamento de Informática Universidad Técnica.
Transcripción de la presentación:

Compilación de Lenguajes Funcionales Perezosos Gustavo Betarte

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

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

Cálculo Lambda Un cálculo que captura el aspecto computacional de la noción de función (Church [1932-1933, 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)

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) e2 ® 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

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.

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.

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.

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.

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

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.

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

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

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

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)) => (+ 20 20) => 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) => (+ 20 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

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) 20 Evaluación perezosa (call-by-need) : Orden normal de reducción + sharing Argumentos de funciones son evaluados a lo sumo una vez

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

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]

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

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.

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

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

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

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

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