Title: Unidad III Programacin Funcional
1Unidad III Programación Funcional
- M.C. Juan Carlos Olivares Rojas
2Agenda
- 3.1 Recursividad como base de control de flujo
-
- 3.2 Listas como esencia en el manejo de datos
-
- 3.3 Lenguajes representativos LISP y Scheme
3Introducción
- Creado por John McCartney en 1958. Viene del
acrónimo LISt Processing. - Su paradigma de programación es la programación
funcional por que todo se basa en el concepto de
función. - Su utilización en Inteligencia Artificial fue su
gran éxito.
4Introducción
- Los Componentes Básicos de LISP son átomos y
listas. - Los átomos pueden ser cualquier combinación de
letras como CASA, ITM, PIEDRA, etc. - Las listas son cualquier combinación de átomos
encerrados entre paréntesis. Se pueden tener
listas anidadas.
5Introducción
- Ejemplos de listas
- (Esta es una lista)
- (EstaEsOtraLista)
- (Lista (anidada))
- El vocablo término se utilizará para
identificar un elemento de una lista ya sea átomo
o sublista.
6Programación Funcional.
- Está caracterizada por el principio funcional.
- El valor de una expresión depende sólo de los
valores de sus subexpresiones, si las tiene. - AB es simplemente la suma de A y B.
- Se excluye las asignaciones
7Programación Funcional.
- La mayoría de los lenguajes que lo implementan
son impuros. - Permiten asignaciones.
- Estilo de programación procedimental.
- Los usuarios no deben preocuparse por el manejo
de memoria. - Ciertas operaciones asignan espacios de
almacenamiento en el momento necesario.
8Programación Funcional
- El almacenamiento que se vuelve inaccesible se
libera. - Recolección de basura.
- Las funciones son valores de primera clase.
- Tienen la misma jerarquía que cualquier otro
valor.
9Programación Funcional
- Puede ser el valor de una expresión.
- Puede pasarse como argumento.
- Puede colocarse en una estructura de datos.
10Programación Funcional.
- Lenguajes de Paradigma Funcional.
- LISP
- SCHEME
- COMMON LISP
- ML
- Haskell
11Programación Funcional.
- Una función matemática es un mapeo de miembros de
un conjunto llamado dominio, hacia otro conjunto
llamado contra-dominio. - Toda definición de una función debe incluir de
manera explicita o implícita - Dominio (Puede ser el resultado de un producto
cruz) - Contra-dominio
- Mapeo
12Programación Funcional.
- Una función regresa solo un valor del
contra-dominio para cada valor del dominio. - Es función?
13Programación Funcional.
- El orden de evaluación de sus expresiones de
mapeo, es controlada por expresiones recursivas y
condicionales. - Factorial.
14Programación Funcional.
- Siempre definen los mismos valores, para un mismo
conjunto de valores. - Una función define un valor.
- No una serie de operaciones sobre valores de una
memoria, para producir dicho valor. - Esto implica que no hay variables en el sentido
estricto de los lenguajes imperativos.
15Programación Funcional
- Variables que representan una localidad de
memoria. - Definición de funciones
- Nombre.
- Lista de parámetros entre paréntesis.
- Expresión de mapeo.
- cubo(x)xxx
- Donde x es un número real.
16Programación Funcional.
- Los lenguajes funcionales, no tienen una
construcción explícita para ciclos tal como FOR,
WHILE, etc., - Utilizan una técnica de programación conocida
como recursividad. - Aplicar una función como parte de la definición
de esa misma función.
17Programación Funcional
- Debe existir una condición terminal, con el
objeto de que la función se bifurque hacia una
resolución no recursiva en algún punto. - De lo contrario, la función entra en un bucle
infinito y nunca finaliza. - Los lenguajes suelen ser tradicionalmente
interpretados. Existen solo algunas opciones para
compilar programas.
18Programación Funcional.
- Por qué no todo mundo usa LISP?
- Sintaxis única.
- LISP ? Lots of Silly Parenthesis (Montón de
paréntesis tontos) - Los paréntesis permiten uniformar la sintaxis.
19Programación Funcional
- Facilita la manipulación de los programas como
datos. - No existen los tipos de datos.
- Parte de los errores semánticos permanecen
ocultos hasta la ejecución. - Implantaciones iniciales ineficientes.
20Estructuras
- Átomos.
- Símbolos de Lisp
- Hacen la función de un identificador.
- Las constantes numéricas también son átomos.
- Listas.
- Estructura de datos.
- Su procesamiento rara vez requiere inserciones o
eliminaciones.
21Programación Funcional.
- Listas.
- Se especifican delimitando sus elementos entre
paréntesis. - Listas simples.
- Todos sus elementos son átomos.
- (A B C D)
- Listas anidadas.
- Sus elementos pueden ser átomos o sublistas.
- (A (B C) D (E (F G)))
22Programación Funcional.
- Listas.
- Internamente se implementan como listas simples
enlazadas. - Cada nodo contiene dos punteros y representa un
elemento. - Un nodo para un átomo contiene su primer puntero
apuntando hacia alguna representación del átomo.
23Programación Funcional
- Un nodo para una sublista contiene su primer
puntero apuntando hacia el primer nodo de la
sublista. - En cualquier caso, el segundo puntero de un nodo,
apunta hacia el nodo siguiente. - A continuación se describen las listas y sus
elementos de forma gráfica.
24Programación Funcional.
- (A B C D)
- (A (B C) D (E (F G)))
25Programación Funcional
- Cómo se usa LISP en IA?
- Se pueden codificar listas que pueden
representarnos hechos, se pueden codificar reglas
de inferencias en base a lista por lo que se
puede hacer Programación Lógica. - El motor de inferencia es implementado por el
usuario pudiendo considerar más tipos de lógicas.
26Programación Funcional
- El compilador/intérprete de LISP que se utilizará
en este curso es el newLisp. - newLISP es un proyecto de software libre que cuya
característica principal es que puede correr en
ambientes gráficos y a su vez generar
representaciones visuales.
27Operaciones Básicas
- A continuación se describen las operaciones
básicas sobre LISP. - La Evaluación de expresiones se realiza a través
del Top Level que es muy semejante al shell visto
en Prolog. - Se escriben expresiones Lisp en el Top-Level, y
el sistema despliega sus valores.
28Operaciones Básicas
- El prompt gt indica que Lisp está esperando a que
una expresión sea escrita. - La expresión es evaluada al pulsar enter.
gt 1 1 gt
29Operaciones Matemáticas
- Las operaciones matemáticas son básicas para
poder implementar el paradigma funcional, a
continuación se describen la forma de realizar
operaciones matemáticas. - Se desea evaluar la siguiente expresión
aritmética ( 2 3)
gt ( 2 3) 5 gt
30Operaciones Matemáticas
- es el operador / función.
- Los números 2 y 3 son sus argumentos.
- Notación prefija.
- Sumar tres parámetros en notación infija implica
Utilizar dos veces el operador suma 235
31Operaciones Matemáticas
- Sumar tres parámetros en notación prefija
- Una sola llamada a la función, con tres
parámetros ( 2 3 5) - es una función
- ( 2 3) es una llamada a la función.
gt ( 2 3 5) 10 gt
32Operaciones Matemáticas
- Cuando LISP evalúa una llamada a alguna función,
lo hace en dos pasos - Los argumentos de la llamada son evaluados de
izquierda a derecha. En este caso los valores de
los parámetros serán, 2 y 3 respectivamente. - Los valores de los argumentos son pasados a la
función nombrada por el operador. En este caso la
función que regresa 5.
33Operaciones Matemáticas
gt () 0 gt ( 2) 2 gt ( 2 3) 5 gt ( 2 3 5) 10 gt
34Operaciones Matemáticas
- Como los operadores pueden tomar un número
variable de argumentos, es necesario utilizar los
paréntesis para indicar donde inicia y donde
termina una expresión. - Las expresiones pueden anidarse. Por ejemplo
(7-1)/(4-2)
gt (/ (- 7 1)(- 4 2)) 3
35Operaciones Matemáticas
- Si alguno de los argumentos es una llamada de
función, ésta será evaluada acorde a las reglas. - Los argumentos de la llamada son evaluados de
izquierda a derecha. - Los valores de los argumentos son pasados a la
función nombrada por el operador. - Evaluar (/ (- 7 1) (- 4 2))
36Operaciones Matemáticas
- Lisp evalúa el primer argumento de izquierda a
derecha (-7 1). - 7 es evaluado como 7 y 1 como 1.
- Estos valores son pasados a la función - que
regresa 6. - El siguiente argumento (- 4 2) es evaluado.
37Operaciones Matemáticas
- 4 es evaluado como 4 y 2 como 2.
- Estos valores son pasados a la función - que
regresa 2. - Los valores 6 y 2 son pasados a la función / que
regresa 3.
38Operaciones Matemáticas
- Un operador que no sigue la regla de evaluación
es quote ( ) - La regla de evaluación de quote es
- No hacer nada, solo desplegar lo que el usuario
tecleó. - El operador quote es una forma de evitar que una
expresión sea evaluada.
39Operaciones Matemáticas
gt (quote ( 2 3)) ( 2 3) gt ( 2 3) ( 2 3)
- Tipos de átomos
- Entero Se escribe como una secuencia de dígitos.
Ejemplo 256. - Cadena Secuencia de caracteres que se delimita
por comillas. Ejemplo Carpe Diem.
40Operaciones Matemáticas
- Enteros y cadenas se evalúan a ellos mismos.
- Los símbolos son palabras. Normalmente se evalúan
como si estuvieran escritos en mayúsculas,
independientemente de como fueron tecleados. - Los símbolos por lo general no evalúan a si
mismos. Es necesario referirse a ellos.
gt Amarone AMARONE
41Operaciones Matemáticas
- Las listas se representan como cero o más
elementos entre paréntesis. - Los elementos pueden ser de cualquier tipo,
incluidas las listas. - Se debe usar quote con las listas, pues de otra
forma Lisp las tomaría como una llamada a
función.
42Operaciones Matemáticas
- Un sólo quote protege a toda la expresión,
incluidas las expresiones en ella. - Se puede construir listas usando el operador list
que es una función, y por lo tanto, sus
argumentos son evaluados.
gt (Mis 2 "ciudades") (MIS 2 "CIUDADES") gt (La
lista (a b c) tiene 3 elementos) (LA LISTA (A B
C) TIENE 3 ELEMENTOS)
43Operaciones Matemáticas
- Estética minimalista y pragmática
- Los programas Lisp se representan como listas.
- Un programa Lisp puede generar código Lisp. Por
eso es necesario quote.
gt (list mis ( 4 2) "colegas") (MIS 6 COLEGAS)
44Operaciones Matemáticas
- Si una lista es precedida por el operador quote,
la evaluación regresa la misma lista. - En otro caso, la lista es evaluada como si fuese
código.
gt (list ( 2 3) ( 2 3)) (( 2 3) 5)
45Operaciones Matemáticas
- En Lisp hay dos formas de representar la lista
vacía - Con un par de paréntesis
- Con el símbolo NIL.
gt () NIL gt NIL NIL
46Operaciones Matemáticas
- La función cons construye listas.
- Si su segundo argumento es una lista, regresa una
nueva lista con el primer argumento agregado en
el frente.
gt (cons a (b c d)) (A B C D) gt (cons a (cons
b nil)) (A B)
47Operaciones Matemáticas
- El segundo ejemplo es equivalente a
- Las funciones primitivas para accesar los
elementos de una lista son car y cdr. - El car de una lista es su primer elemento (el más
a la izquierda) .
gt (list a b) (A B)
48Operaciones Matemáticas
- El cdr es el resto de la lista (menos el primer
elemento). - En realidad en newLisp car se hace a través de
first y cdr a través de rest.
gt (first '(a b c)) a gt (rest '(a b c)) (b c)
49Estructuras de Control
- Ya se mencionó que no existen en LISP estructuras
de control semejantes a los lenguajes
procedimentales u orientado a objetos. - Un Predicado es una función cuyo valor de regreso
se interpreta como un valor de verdad (verdadero
o falso). - Es común que el símbolo de un predicado termine
en p.
50Estructuras de Control
- Como nil juega dos roles en Lisp, las funciones
null (lista vacía) y not (negación) hacen
exactamente lo mismo - La condicional (if) Normalmente toma tres
argumentos - una expresión a probar (test)
gt (null nil) T gt (not nil) T
51Estructuras de Control
- una expresión entonces (then) que se evalua si
test es T. - una expresión si no (else) que se evalua si test
es NIL.
gt (if (listp (a b c d)) ( 1 2) ( 3 4)) 3 gt (if
(listp 34) ( 1 2) ( 3 4)) 7
52Estructuras de Control
- La condicional (if) es una macro no una función.
- Los argumentos de una función siempre se evalúan.
If solo evalúa dos test y (then o else) - Si bien el default para representar verdadero es
T, todo excepto nil cuenta como verdadero en un
contexto lógico
gt (if 27 1 2) 1 gt (if nil 1 2) 2
53Estructuras de Control
- Los operadores lógicos (and, or) toman cualquier
número de argumentos, pero solo evalúan los
necesarios para decidir que valor regresar. - Si todos los argumentos son verdaderos
(diferentes de nil), entonces and regresa el
valor del último argumento.
gt (and t ( 1 2)) 3
54Estructuras de Control
- Si uno de los argumentos de and es falso, ninguno
de los operadores siguientes es evaluado, y
regresa nil. - De manera similar, or se detiene en cuanto
encuentra un elemento verdadero. - Los operadores lógicos tampoco se consideran
funciones, sino macros.
gt (or nil nil ( 1 2) nil) 3
55Funciones de Predicados
- Es posible definir nuevas funciones con defun que
toma normalmente tres argumentos - Un nombre.
- Una lista de parámetros
- Una o más expresiones que conforman el cuerpo de
la función.
56Funciones
- El primer argumento de define indica que el
nombre de la función definida será area. - Los demás argumentos allí se muestran.
gt (define (area base altura) ( base
altura)) (lambda (base altura) ( base altura)) gt
(area 2 3) 6
57Funciones
- Cuando la variable representa el argumento de una
función, se conoce como parámetro. - Un símbolo usado de esta forma se conoce como
variable. - El resto de la definición indica lo que se debe
hacer para calcular el valor de la función.
58Funciones
- Símbolos y listas deben protegerse con quote para
ser accedidos. - Una lista debe protegerse porque de otra forma es
procesada como si fuese código. - Un símbolo debe protegerse porque de otra forma
es procesado como si fuese una variable.
59Funciones
- La definición de una función corresponde a la
versión generalizada de una expresión Lisp. - La siguiente expresión verifica si la suma de 1 y
4 es mayor que 3
gt (gt ( 1 4) 3) T
60Funciones
- Substituyendo los números partículares por
variables, podemos definir una función que
verifica si la suma de sus dos primeros
argumentos es mayor que el tercero
gt (define (suma-mayor-que x y z) (gt ( x y)
z)) (lambda (x y z) (gt ( x y) z)) gt
(suma-mayor-que 1 4 3) true
61Funciones
- Lisp no distigue entre programa, procedimiento y
función. - Si se desea considerar una función en partícular
como main, es posible hacerlo, pero cualquier
función puede ser llamada desde el top-level. - Entre otras cosas, esto significa que posible
probar un programa, pieza por pieza, conforme se
va escribiendo.
62Funciones
- Programación incremental (bottom-up).
- Las funciones que hemos definido hasta ahora,
llaman a otras funciones para hacer una parte de
sus cálculos. Por ejemplo suma-mayor-que llama a
las funciones y gt. - Una función puede llamar a cualquier otra
función, incluida ella misma.
63Actividad
- Realizar una función para calcular el área de un
triángulo en base a sus lados, utilizar la
fórmula ya antes descrita, considerar la
validación de los datos. - Realizar una función que permita calcular el
promedio de un número variable de argumentos, por
ejemplo (promedio 10 2 3 5) al evaluarse
devuelve 20 también se podría ubicar cómo
(promedio 2 7) regresaría 4.5
64Funciones
- Una función que se llama a si misma se conoce
como recursiva. - Recordar que las funciones recursivas tienen
definidas un paso base para poder salir de la
recursión y un paso recursivo. - A continuación se muestra un ejemplo de la
función de Fibonnaci, definir la función
multiplicación de manera recursiva (utilizando
sumas).
65Funciones
- Función Fibonacci
- (define (fibonacci n)
- (if (lt n 2)
- 1
- ( (fibonacci (- n 1))
- (fibonacci (- n 2)))))
- gt_ (fibonacci 10)
- 89
66Funciones
- Metáfora de la recursividad procesos que se van
resolviendo. - Un estudiante está interesado en Lisp.
- Va a la biblioteca y el proceso que utilizaría
para examinar un documento es el siguiente - Obtener una copia del documento que le interesa.
67Funciones
- Buscar en él la información relativa a Lisp.
- Si el documento menciona otros documentos que
puede ser útiles, examinarlos. - También se deben tomar en cuenta algunos factores
no funcionales.
68Funciones
- Para poder operar aritméticamente con dobles se
ocupan las funciones add, sub, mul y div. - La función list? Permite saber si un argumento es
un lista o no. - Null? Permite saber si una lista está vacía o no.
- La función symbol? Permite determinar si un
argumento es un símbolo o no.
69Funciones
- La función number? Permite saber si un argumento
es numérico o no. - Prototipo de función recursiva
- (define (suma lista)
- (if (null? lista) 0
- ( (first lista) (suma (rest lista)))
- ))
70Funciones
- Cómo se mandaría llamar la función para sumar
números del 1 al 5? - Realizar una función llamada longitud para
definir el número de argumentos que tiene una
lista. (longitud (1 2 4)). Devuelve 3 - Realizar una función llamada miembro para
encontrar la sublista a partir de la cual se
encuentra dicho elemento. (miembro 3 (1 2 3 4
5)) imprime como salida (3 4 5).
71Funciones
- Uno de los operadores más comunes en Lisp es let,
que permite la creación de nuevas variables
locales. - Una expresión let tiene dos partes
- Primero viene una lista de expresiones definiendo
las nuevas variables locales, cada una de ellas
con la forma (variable expresión).
gt (let ((x 1)(y 2)) ( x y)) 3
72Funciones
- Cada variable es inicializada con el valor que
regrese la expresión asociada a ella. En el
ejemplo anterior se han creado dos variables, x e
y, con los valores 1 y 2 respectivamente. - Esas variables son válidas dentro del cuerpo de
let.
73Funciones
- Una expresión let tiene dos partes
- Después de la lista de variables y valores, viene
el cuerpo de let constituido por una serie de
expresiones que son evaluadas en orden. - En el ejemplo, sólo hay una llamada a ..
74Funciones
- En newLisp el operador de asignación más común es
define. - Se puede usar para asignar valores a cualquier
tipo de variable.
gt (define glob 2000) 2000 gt (let ((n 10))
(define n 2) n) 2
75Funciones
- Cuando el primer argumento de setf es un símbolo
que no es el nombre de una variable local, se
asume que se trata de una variable global.
gt (define x (a b c)) (A B C)
76 GUI en LISP
- (load (append (env "NEWLISPDIR")
"/guiserver.lsp")) - (gsinit)
- (gsframe 'Mixer 200 200 400 300 "Mixer")
- (gsset-resizable 'Mixer nil)
- (gsset-border-layout 'Mixer)
- (gspanel 'SliderPanel)
- (gsset-grid-layout 'SliderPanel 3 1)
- (gspanel 'RedPanel)
- (gspanel 'GreenPanel)
77GUI en LISP
- (gspanel 'BluePanel)
- (gslabel 'Red "Red" "left" 50 10 )
- (gslabel 'Green "Green" "left" 50 10 )
- (gslabel 'Blue "Blue" "left" 50 10 )
- (gsslider 'RedSlider 'slider-handler
"horizontal" 0 100 0) - (gsslider 'GreenSlider 'slider-handler
"horizontal" 0 100 0) - (gsslider 'BlueSlider 'slider-handler
"horizontal" 0 100 0)
78GUI en LISP
- (gslabel 'RedSliderStatus "0" "right" 50 10)
- (gslabel 'GreenSliderStatus "0" "right" 50 10)
- (gslabel 'BlueSliderStatus "0" "right" 50 10)
- (gsadd-to 'RedPanel 'Red 'RedSlider
'RedSliderStatus) - (gsadd-to 'GreenPanel 'Green 'GreenSlider
'GreenSliderStatus) - (gsadd-to 'BluePanel 'Blue 'BlueSlider
'BlueSliderStatus) - (gsadd-to 'SliderPanel 'RedPanel 'GreenPanel
'BluePanel)
79GUI en LISP
- (gscanvas 'Swatch)
- (gslabel 'Value "")
- (gsset-font 'Value "Sans Serif" 16)
- (gsadd-to 'Mixer 'SliderPanel "north" 'Swatch
"center" 'Value "south") - (gsset-visible 'Mixer true)
- (set 'red 0 'green 0 'blue 0)
- (gsset-color 'Swatch (list red green blue))
- (gsset-text 'Value (string (list red green
blue)))
80GUI en LISP
- (define (slider-handler id value)
- (cond
- (( id "MAINRedSlider")
- (set 'red (div value 100))
- (gsset-text 'RedSliderStatus (string red)))
- (( id "MAINGreenSlider")
- (set 'green (div value 100))
- (gsset-text 'GreenSliderStatus (string green)))
81GUI en LISP
- (( id "MAINBlueSlider")
- (set 'blue (div value 100))
- (gsset-text 'BlueSliderStatus (string blue)))
- )
- (gsset-color 'Swatch (list red green blue))
- (gsset-text 'Value (string (list red green
blue)))) - (gslisten)
82GUI en LISP
- Uso de Bibliotecas de Windows
- (import "user32.dll" "MessageBoxA")
- (MessageBoxA 0 "Hola Mundo!"
- "Ejemplo de GUI" 0)
- Se pueden crear DLLs em lenguajes como C y
poder utilizarlo em funciones más complejas.
83Entradas y Salidas
- Para la definición de salidas se puede utilizar
la función print. - La función time devuelve el tiempo en que tarda
una función en evaluarse.
gt (print ( 2 3 4 1)) 1010 gt ( ( 2 3) (/ 3 2)
9) 16 gt ( (print ( 2 3)) (print (/ 3 2))
(print 9)) 6 1 9 16 gt time (promedio 1 2) 0
84Entradas y Salidas
- Se puede guardar programas con la extensión .lsp
para después poderlos ejecutar. - A continuación se muestra una tabla con las
principales funciones definidas en la mayoría de
los dialectos de LISP.
gt (load f/myfile.lisp") Ejecuta todo el
script gt (read-file msgbox.lsp) Visualiza todo
el script
85Funciones
86Más de LISP
- imprimir los primeros 10 números de fibonacci
- (for (n 1 10)
- (println n " " (fibonacci n)))
- (max 1.1 43 23 12 -1 53 4 32) Cuanto da?
- Qué hacen?
- (directory "/")
- (exit)
87Más de LISP
- (set 'alphabet "abcdefghijklmnopqrstuvwxyz")
- (upper-case alphabet) ?
- (set 'x ( 2 2 )) ?
- (set 'y '( 2 2)) ?
- (dotimes (c 10)
- (println c " por 3 es " ( c 3)))
88Más de LISP
- Ejemplo de un switch
- (if
- (lt x 0) (set 'a "imposible")
- (lt x 10) (set 'a "pequeño")
- (lt x 20) (set 'a "medio")
- (gt x 20) (set 'a "largo")
- )
89Más de LISP
- (set 'counter 1)
- (dolist (i (sequence -5 5))
- (println "Elemento " counter " " i)
- (inc 'counter))
- (dolist (i (sequence -5 5))
- (println "Element " idx " " i))
90Más de LISP
- Switch
- (case n
- (1 (println "un"))
- (2 (println "deux"))
- (3 (println "trois"))
- (4 (println "quatre")))
- (randomize (sequence 1 99))
- (dup 1 6)
91Más de LISP
- (set 'L '(a b c (d e (f g) h i) j k))
- (define (walk-tree tree)
- (cond (( tree '()) true)
- ((atom? (first tree))
- (println (first tree))
- (walk-tree (rest tree)))
- (true (walk-tree (first tree))
- (walk-tree (rest tree)))))
92LISP
- (define (walk-tree tree)
- (dolist (elmnt tree)
- (if (list? elmnt)
- (walk-tree elmnt)
- (println elmnt))))
- gt_ (walk-tree L)
93Bibliografía
- Rico, F. (2007) Programación Funcional, Material
de la Materia Lenguajes de Programación, UVAQ
Noviembre 2007. - Montes, M. y Villaseñor L. (2008) Fundamentos de
Inteligencia Artificial Métodos básicos de
solución de problemas, Instituto Nacional de
Astrofísica, Óptica y Electrónica, Puebla, México.
94Preguntas, dudas y comentarios?