tema 3: características de la programación funcional · datos compuestos en scheme • en scheme...

28
Tema 3: Características de la programación funcional Sesión 8: El paradigma funcional (4) jueves 3 de marzo de 2011

Upload: others

Post on 14-Mar-2020

10 views

Category:

Documents


0 download

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

Hoy veremos

• Características de la programación funcional en LISP/Scheme

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