tema 3: características de la programación funcional · datos compuestos en scheme • en scheme...
TRANSCRIPT
Tema 3: Características de la programación funcional
Sesión 8: El paradigma funcional (4)
jueves 3 de marzo de 2011
Referencias
• Capítulo 10 PLP: Functional Languages
• Capítulo 2.2 SICP, Abelson & Sussman
jueves 3 de marzo de 2011
Características de la programación funcional
• Evaluación sin efectos laterales: paradigma declarativo y modelo de sustitución
• Funciones como tipos de datos primitivos: forma especial lambda
• Ámbitos de variables: forma especial let
• Dualidad entre datos y programas: formas especiales eval y apply
• Listas como elemento fundamental de procesamiento: parejas, cons, car y cdr
• Recursión
jueves 3 de marzo de 2011
Ejemplo de dualidad de datos y programa calculadora
• Este programa no es funcional: realiza pasos de ejecución para leer las expresiones introducidas por el usuario y para imprimir el resultado de su evaluación.
(define (calculadora) (display "Introduce parámetros entre paréntesis: ") (define params (read)) (display "Introduce cuerpo:") (define cuerpo (read)) (define func (eval (append '(lambda) (list params) (list cuerpo)))) (display "Introduce argumentos entre paréntesis: ") (define args (read)) (apply func args))
jueves 3 de marzo de 2011
Ejemplo de dualidad de datos y programa calculadora
• Es importante darse cuenta de que la expresión:
• devuelve una lista que es una expresión lambda correcta, cuya evaluación va a crear un procedimiento al que se llama después. Por ejemplo:
• Si hiciéramos (append '(lambda) params cuerpo) ¿qué obtendríamos?
(append '(lambda) (list params) (list cuerpo))
(define params '(x y))(define cuerpo '(+ x y))
jueves 3 de marzo de 2011
Ejemplo de dualidad de datos y programa calculadora
• Es importante darse cuenta de que la expresión:
• devuelve una lista que es una expresión lambda correcta, cuya evaluación va a crear un procedimiento al que se llama después. Por ejemplo:
• Si hiciéramos (append '(lambda) params cuerpo) obtendríamos una lista con 6 elementos:
• Necesitamos obtener la lista '(lambda (x y) (+ x y)), una lista de 3 elementos
(append '(lambda) (list params) (list cuerpo))
(define params '(x y))(define cuerpo '(+ x y))
(append '(lambda) params cuerpo)-> (lambda x y + x y)
jueves 3 de marzo de 2011
Datos compuestos en Scheme
• En Scheme es posible crear datos compuestos.
• La forma de hacerlo es definiendo una construcción muy simple y usando esa construcción simple para hacer cosas más complicadas.
• El tipo de dato compuesto más simple es la pareja: una entidad formada por dos elementos.
• Se utiliza la función cons para construirla.
(cons 1 2)(1 . 2)
jueves 3 de marzo de 2011
Diagramas caja y puntero
• Las parejas se representan mediante este tipo de figuras
(cons 1 2)(1 . 2)
jueves 3 de marzo de 2011
Funciones de acceso a una pareja
• Podemos obtener el elemento correspondiente a la parte izquierda con el operador car y su parte derecha con el operador cdr
• Definición declarativa: Las funciones cons, car y cdr quedan perfectamente definidas con las siguientes ecuaciones
(define c (cons 1 2))> (car c) 1> (cdr c) 2
(car (cons x y)) = x(cdr (cons x y)) = y
jueves 3 de marzo de 2011
Nota histórica
• ¿De dónde vienen los nombres car y cdr?
• Realmente los nombres eran CAR y CDR (en mayúsculas)
• La historia se remonta al año 1959, en los orígenes del LISP y tiene que ver con el nombre que se les daba a ciertos registros de la memoria del IBM 709.
• Explicación completa: http://www.iwriteiam.nl/HaCAR_CDR.html
jueves 3 de marzo de 2011
Las parejas pueden contener cualquier tipo de dato
> (define c (cons 'hola #f))> (car c)'hola> (cdr c)#f
jueves 3 de marzo de 2011
Las parejas pueden contener cualquier tipo de dato
> (define c (cons 'hola #f))> (car c)'hola> (cdr c)#f
(define p1 (cons (lambda (x) (+ x 3)) 5))
• ¿Cómo se podría llamar a la función de la parte izquierda de la pareja con la parte derecha como argumento?
jueves 3 de marzo de 2011
Las parejas pueden contener cualquier tipo de dato
> (define c (cons 'hola #f))> (car c)'hola> (cdr c)#f
(define p1 (cons (lambda (x) (+ x 3)) 5))
• ¿Cómo se podría llamar a la función de la parte izquierda de la pareja con la parte derecha como argumento?
((car p1) (cdr p1)) -> 8
jueves 3 de marzo de 2011
Seguimos en el paradigma funcional
• Seguimos en el paradigma funcional
• Una vez creada una pareja no es posible modificar sus contenidos.
• Aunque Scheme tiene primitivas para modificar el contenido de las parejas.
jueves 3 de marzo de 2011
Las parejas son un tipo de dato de primer orden
• Una pareja es también un tipo de datos de primer orden: puede pasarse como argumento y devolverse como resultado de una función.
> (define (doble-car pareja) (* 2 (car pareja)))> (doble-car (cons 4 2))8
> (define (doble-pareja pareja) (cons (doble-car pareja) (doble-cdr pareja)))> (doble-pareja (cons 2 3))(4 . 6)
jueves 3 de marzo de 2011
Propiedad de clausura: parejas de parejas
• Las parejas pueden formar parte de otras parejas.
• Esta última propiedad se denomina clausura de la operación cons.
• El resultado de un cons puede usarse para construir otras parejas.
• Ejemplo:
• Expresión equivalente:
(define p1 (cons 1 2))(define p2 (cons 3 4))(define p (cons p1 p2))
(define p (cons (cons 1 2) (cons 3 4)))
jueves 3 de marzo de 2011
Ejemplo
(define p (cons (cons 1 (cons 3 4)) 2))
• ¿Qué figura representa la estructura anterior?
jueves 3 de marzo de 2011
Funciones c????r
• Es equivalente a:
• El nombre de la función se obtiene concatenando a la letra "c", las letras "a" o "d" según hagamos un car o un cdr y terminando con la letra "r"
• Hay definidas 2^4 funciones de este tipo: caaaar, caaadr, …, cddddr.
> (car (cdr (car p)))3
> (cadar p)))3
jueves 3 de marzo de 2011
Función pair?
• La función pair? nos dice si un objeto es atómico o es una pareja
> (pair? 3)#f>(pair? (cons 3 4))#t>(not (pair? (cons 2 3)))#f
jueves 3 de marzo de 2011
Repaso de listas
(list 1 2 3 4)'(1 2 3 4)
(define hola 1)(define que 2)(define tal 3)
(list hola que tal)'(hola que tal)
(define a '(1 2 3))(car a)(cdr a)(length a)(length '())(append '(1) '(2 3 4) '(5 6 7) '())
jueves 3 de marzo de 2011
Construcción de listas con parejas
• Definición recursiva con parejas:
• Una pareja en la que el primer elemento es un dato y el segundo el resto de la lista.
• Un símbolo especial '() que denota la lista vacía
• Ejemplo:
(cons 1 (cons 2 (cons 3 '())))
jueves 3 de marzo de 2011
Lista vacía
• No es un símbolo
• No es una pareja
• Es una lista
> (symbol? '())#f> (pair? '())#f> (length '())0
jueves 3 de marzo de 2011
Funciones list? y null?
• Nos permite comprobar si un dato es una lista
• Para comprobar si una lista está vacía utilizamos la función null?
> (list? '(1 2 3))#t> (list? '())#t> (list? 2)#f
> (null? '())#t
jueves 3 de marzo de 2011
car y cdr para recorrer listas
• Ahora se entiende mejor por qué las funciones que permiten recorrer una lista son car y cdr como en el siguiente ejemplo:
(define lista (cons 1 (cons 2 (cons 3 (cons 4 '())))))(car lista)(cdr lista)
jueves 3 de marzo de 2011
cons para formar una nueva lista
> (define l1 '(1 2 3 4))> (cons 'hola l1)(hola 1 2 3 4)
jueves 3 de marzo de 2011
Ejercicio resuelto
• Define el procedimiento (insertar-list lista l2 n) que reciba dos listas y un número n. Deberá insertar en el mismo nivel, la l2 en la lista en la posición indicada por n (suponemos que n nunca será mayor que la longitud de la lista):
> (define (insertar-list lista l2 n) (if (= n 0) (append l2 lista) (cons (car lista) (insertar-list (cdr lista) l2 (- n 1)))))> (insertar-list '(1 2 3 4) '(a b) 3)(1 2 3 a b 4)
jueves 3 de marzo de 2011
Ejercicios
• Dibuja el diagrama caja y puntero asociado a estas estructuras de datos:
• Dibuja el diagrama caja y puntero asociado a esta estructura de datos:
• Implementa la función mi-lis-ref que reciba un número n y una lista como argumento y devuelva el elemento n-ésimo de la lista (empezando a contar en 0).
• Implementa la función mi-list-tail que reciba un número n y una lista como argumento y devuelva la lista resultante de quitar n elementos de la lista original
((x) y z)(x (y z))((a) b (c ()))
(cons (cons 2 (cons 3 (cons 4 ‘()))) (cons 1 2))
jueves 3 de marzo de 2011