1 / 67

PROGRAMACIÓN FUNCIONAL LISP

PROGRAMACIÓN FUNCIONAL LISP. Concepto Matemático de Función. Cubo(x) = x 3 Cubo: R  R Dominio : Codominio (Intervalo). Asignación y Funciones. Cubo(x) = x 3 En los lenguajes imperativos la variable x : Es una ubicación en memoria

camden
Download Presentation

PROGRAMACIÓN FUNCIONAL LISP

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. PROGRAMACIÓN FUNCIONALLISP

  2. Concepto Matemático de Función Cubo(x) = x3Cubo: RRDominio : Codominio (Intervalo)

  3. Asignación y Funciones Cubo(x) = x3 En los lenguajes imperativos la variable x: • Es una ubicación en memoria • x = x + 1, significa “actualizar el estado del programa añadiendo 1 al valor almacenado en la celda de memoria llamada x y después almacenar la suma en dicha celda” • l-value = r-value

  4. … Asignación y Funciones Cubo(x) = x3 En matemáticas la variable x: • Es el valor de una expresión real • Es inmutable. • No existe el concepto de “estado” ni de “valor almacenado”

  5. … Asignación y Funciones • Programación funcional pura concepto matemático de función • Lenguajes funcionales  Impuros( Mantienen algún tipo de asignación ) • Transparencia Referencial El valor de una función depende SÓLO de sus parámetros • Cálculo Lambda

  6. Cálculo Lambda • Alonzo Church & Stephen Cole Kleene ( 1930’s ) • Sistema formal para investigar definición y aplicación de funciones y recursión • Permite definir lo que es una función “computable” e implementar cualquiera de ellas • Equivalente a las “Máquinas de Turing” • Enfatiza el uso de reglas de transformación más allá de la máquina que las implementa, por lo que se acerca más al software que al hardware • Principal influencia de los lenguajes de programación funcionales (especialmente de LISP)

  7. … Cálculo Lambda • Expresiones lambda: <expr> ::= <identificador> <expr> ::= (λ <identificador> . <expr>) • Denominada abstracción <expr> ::= (<expr> <expr>) • Denominada aplicación (a un argumento) Las dos primeras generan funciones.

  8. … Cálculo Lambda Ejemplos: • x ó (x)  identificador • (λx.x)  Abstracción • ((λx.x)(λy.y))  Aplicación + abstracción • (λx.(zx))  Abstracción + aplicación • ( ( λy.( (λx.xyz)a ) )b )  Expresión compleja

  9. … Cálculo Lambda Definiciones: • En la expresión lambda (λx.M), siendo M, a su vez, cualquier expresión lambda, se dice que el identificador x está unido en la subexpresión M. Cualquier identificador que no esté unido se dice que es libre. Reglas para la determinación de variables libres: ( x es un identificador y M, N son expresiones lambda ) • libres( x ) = x • libres( MN ) = libres( M )  libres( N ) • libres( (λx.M) ) = libres( M ) – { x }

  10. … Cálculo Lambda Conversión : • Los nombres de las variables no son importantes. (λx.x) == (λy.y) • Si V y W son variables, E es una expresión lambda y E[V/W] significa la expresión E, con el remplazo de todas las ocurrencias libres de V por W, entonces: (λV.E) == ( λW.E[V/W] ) si W no está libre en E y W no está unida por una λ en E cuando remplaza a V. Esto nos dice, por ejemplo, que: ( (λx.(λx.x)) x ) == ( (λy.(λx.x)) y )

  11. … Cálculo Lambda Reducción : • Expresa la idea de la aplicación de una función, esto es, si V es una variable y E, E’ son expresiones lambda, entonces: ( (λV.E) E’ ) == E[V/E’] si todas las ocurrencias libres en E’ permanecen libres en E[V/E’]. Esto nos dice, por ejemplo, que: ( ( λy.( (λx.xyz)a ) )b )  ( (λy.ayz)b )  ( abz ) • Una expresión – λque ya no permite reducciones , esto es, que no tiene subexpresiones de tipo ( (λV.E) E’) se denomina forma normal.

  12. … Cálculo Lambda El significado de las expresiones lambda consiste en la evaluación de las funciones que las componen: • Por ejemplo, la función “agrega dos” f(x) = x + 2, en cálculo lambda se expresa: ( λx . x + 2 ) ó ( λy . y + 2 ) – según la conversión  – • Aplicándola a un cierto valor, resulta de la reducción : ( ( λx . x + 2 )3 )  ( 3 + 2 )  ( 5 ) • Una función de 2 variables en cálculo lambda se expresa como una función de 1 argumento que devuelve una función de 1 argumento. Por ejemplo, la función de 2 variables f( x, y ) = x - y: ( λx . ( λy . x - y ) ) • Aplicándola a un cierto valor, resulta de la reducción : ( ( λx . ( λy . x - y )2 )7 )  ( ( λx . x - 2 )7 )  ( 7 – 2 )  ( 5 )

  13. … Cálculo Lambda • La forma normal de una expresión lambda se utiliza para determinar la relación de equivalencia entre expresiones, esto es, si dos expresiones lambda, reducidas a su forma normal, son iguales, se dice que las formas originales (y las normales) son equivalentes. • A pesar de lo anterior, no a toda expresión lambda le corresponde una forma normal. Ejemplo: Funciones que implícitamente se definen recursivamente o, que definen conjuntos infinitos. • El cálculo lambda puro desarrollado por Church no ofrece interpretación de símbolos. Por tanto ( ( λx . x * x )5 )  (5 * 5), sin mayor reducción. Sólo en el cálculo lambda aplicado, como los lenguajes de programación funcionales, se reduciría a ( 25 ). • Estableciendo ciertas restricciones al cálculo lambda se obtiene el cálculo combinacional / de predicados.

  14. … Interactuando con LISP …

  15. Componentes de los Lenguajes Funcionales • Expresiones – S: Unidades sintácticas que representan datos y sentencias de programa en Lisp. ( S - Symbolic ) • Átomos • Numéricos: Enteros o de punto flotante ( -25, 1.75, etc. ) • Símbolos o “átomos literales”: Identificadores en otros lenguajes, utilizados mayormente como variables. ( X, MANZANA, +, *, P1, etc. ). A diferencia de otros lenguajes, pueden iniciar con dígitos, caracteres de puntuación y aún caracteres especiales. Lisp no es sensible a minúsculas y mayúsculas. • Carácter ( #\a, #\b, #\{, etc. ) • String ( “Adiós”, “abc”, “Lisp”, etc. ) • Arreglo: Colección de enteros, caracteres, símbolos u otras expresiones – S, accesados con el nombre del arreglo y uno o varios subíndices ( ( (a b c)(1 2 3) ), (128 128), etc. )

  16. Componentes de los Lenguajes Funcionales • Compuestas • Listas: Consiste de cero o más expresiones – S (que pueden ser atómicas o compuestas a su vez), separadas por espacios en blanco y encerradas entre paréntesis. La lista vacía o de cero componentes se escribe “()”. También se utiliza en forma equivalente un SÍMBOLO especial para denotar esta lista: NIL. • Formas: Instrucciones. • Funcionales: Lista cuyo primer elemento es el nombre de una función y los restantes son los parámetros de la misma ( +, 1+, car, cdr, etc. ) • Macros: Lista cuyo primer componente es el nombre de una macro, la cual se “expande” como llamada a una forma funcional. Sirven como envolturas para crear “nuevas” formas funcionales. • Especiales: Formas que controlan la ejecución de un programa en Lisp ( IF, COND, DOLIST, etc. )

  17. Algunas Funciones Elementales Expresiones – S = componente1 + componente2 + … + componenteN • Manipulación de la estructura de una lista • CONS: Forma una nueva expresión – S compuesta, de otras dos proporcionadas. CONStruye la nueva expresión, por eso tal objeto se le denomina un cons. (consexpS1expS2) • CAR: Devuelve la primera expresión – S que compone a la expresión proporcionada. Contents of Address of Register – Macro del ensamblador de la computadora IBM 704 en la que por primera vez se implementó Lisp. También se proporciona el nombre FIRST para esta misma funcionalidad. • (carexpS) ó (firstexpS) • CDR “Cúder”: Devuelve la “otra mitad” que compone a la expresión proporcionada (siempre una lista). Contents of Decrement of Register – Otra macro del ensamblador citado. También se proporciona el nombre REST para esta misma funcionalidad. • (cdrexpS) ó (restexpS) CAR y CDR devuelven NIL si su argumento es NIL.

  18. … Algunas Funciones Elementales • No siempre CAR + CDR deshacen lo hecho por CONS. • Combinaciones de CAR y CDR: (car (car x))  (caar x) (car (cdr x))  (cadr x)  Segunda expresión – S de x (cdr (car x))  (cdar x) (cdr (cdr x))  (cddr x) (car (cdr (cdr x)))  (caddr x)  Tercera expresión – S … permutaciones hasta de 4 A’s y D’s. “C + A (por cada car) + D (por cada cdr) + R” • Funciones equivalentes: FIRST, SECOND, THIRD, … , TENTH y NTH. • (nthnlista)

  19. … Algunas Funciones Elementales • APPEND: Devuelve una nueva lista, resultado de la concatenación de las listas dadas como parámetros. (appendlista1lista2 … listak) • LIST: Devuelve la lista de los k – valores resultado de la evaluación de las k expresiones – S proporcionadas como parámetros. • (listexpS1expS2 … expSk) • Evaluación de Formas Funcionales Para evaluar una forma funcional, el intérprete de Lisp evalúa primeramente, en forma recursiva si es necesario, los parámetros de la misma, por lo que se puede utilizar QUOTE para evitar tal comportamiento en donde así sea requerido, o su forma abreviada consistente en el carácter ’.

  20. … Algunas Funciones Elementales • Asignación • SET: Evalúa ambas expresiones – S que recibe como parámetros y le asigna al valor global de la primera expresión (por lo que ésta debe ser un símbolo), el valor obtenido de la segunda. Función. • (setexpS1expS2) • SETQ “SETQUOTE”: Evalúa cada expresión – S recibida como parámetro y el valor resultante se lo asigna al símbolo respectivo. Forma Especial. • (setqsimbolo1expS1...simbolokexpSk) • SETF: Equivalente a SETQ, exceptuando que permite la asignación a elementos de arreglos, estructuras y tipos más complejos en los que SETQ falla. Permite que los símbolos respectivos a cada “asignación” sean expresiones, en tal caso, se evalúan éstas antes del procesamiento. Macro. • (setfexpSoSimbolo1expS1...expSoSimbolokexpSk)

  21. Apuntador al CAR Apuntador al CDR Manejo de Memoria • Celdas 2 o 3 palabras (de memoria) de la máquina • Microcomputadoras  4 bytes • Macrocomputadoras  Hasta 8 bytes (64 bits) por celda • Celda  2 apuntadores • Celda cons: Apuntador al CAR + apuntador al CDR

  22. Más Sobre Expresiones - S Formalmente: • Cualquier átomo es una expresión – S, v. gr., cualquier número, símbolo, caracter, string o arreglo es una expresión – S • Si X y Y son expresiones – S, entonces la expresión ( X . Y ) es una expresión – S y se denomina par punteado ( dotted pair ) • Si S1, S2, … , Sk son expresiones – S, con k  0, entonces (S1, S2, … , Sk ) es una expresión – S y se denomina lista • Solamente un objeto formado por la aplicación de un número finito de veces de las reglas 1, 2 y 3 es una expresión - S

  23. A B A A C A B B D C … Manejo de Memoria – Estructura de Datos ( A . B ) ( ( A . B ) . ( C . D ) ) Dotted List: ( (A.B) (C.D) ) ( A . ( B . ( C . NIL ) ) ) Como lista: ( A B C )

  24. CDR-NEXT Elem1 CDR-NORMAL Elem1 - Lx CDR-NEXT Elem3 CDR-NEXT Elem5 … CDR-NORMAL Elem2 - Lx CDR-NEXT Elem2 CDR-NORMAL Cons1 - Lx CDR-NEXT Elem4 CDR-NIL … CDR-NIL CDR - Coding CDR – Code ( 2 bits ): CDR-NORMAL: Primera mitad de celda “normal”. CDR-NEXT: La siguiente celda en memoria contiene el siguiente elemento de la lista (el siguiente CAR). CDR-NIL: Última celda de la lista. Apuntador implícito a NIL. Las funciones de Lisp que remplazan el apuntador al CDR directamente, deben copiar primero el CONS en esa celda y colocar un apuntador de “redirección” a la nueva celda donde está la copia creada.

  25. Unidad de Manejo de Memoria Funciones “CORE” READ, EVAL, APPLY, PRINT, NULL, CONS, CAR, CDR, READ, ATOM, FUNCIONES ARITMETICAS Y FUNCIONES PREDICADOS Lenguaje de bajo nivel Velocidad Librería de Funciones Implementadas en base a las Funciones del núcleo IMPLEMENTACIÓN DE LISP

  26. Memoria Memoria Apuntador freelist Apuntador freelist .… .… Recolección de Basura Recolección De Basura

  27. TABLA DE SIMBOLOS S7 S2 S4 S5 S6 S3 S8 S9 .… S1 S11 S10 .… .… .… .… .… .… … Recolección de Basura – “Marcar y Barrer” Apuntador freelist 1 Bit “Marcar”

  28. Buscar Celdas “Libres” Apuntador freelist .… .… .… Referencia (CDR S1) Buscar Celdas “Ocupadas” Apuntador de Redirección .… .… .… … Recolección de Basura – “Compactar” Datos Copiados Remplazar Referencias Copiar Datos

  29. … Recolección de Basura – “Compactar” • Dada la lentitud del proceso, se utilizan algoritmos incrementales de mucha mayor complejidad, pero de menor grado de interrupción de trabajo.  * 

  30. Predicados y Formas Condicionales Predicados: Funciones que devuelven valores que se interpretan como booleanos ( TRUE / FALSE ). • Cualquier valor que no sea explícitamente NIL se toma como TRUE. • Explícitamente el símbolo T significa TRUE. v. gr.: (< 3 5)  TRUE (> 3 5)  NIL Combinación de predicados • (andexpS1expS2 … expSn)  Conjunción lógica. Macro. • (orexpS1expS2 … expSn)  Disyunción lógica. Macro. • (notexpS) ó (nullexpS)  Negación lógica. Función. • Evalúan en corto circuito.

  31. … Predicados y Formas Condicionales • (atom expS)  T si expS es un átomo • (null expS)  T si expS es NIL • (symbolp expS)  T si expS es un símbolo • (listp expS)  T si expS es una lista • (consp expS)  T si expS es un objeto cons (como listp pero excluye a NIL) • (numberp expS)  T si expS es un átomo numérico Pruebas más específicas del tipo numérico: • integerp, floatp, rationalp y complexp Probar si es cero, par, impar y mayor o menor a cero: • zerop, evenp, oddp, plusp y minusp • stringp, arrayp, vectorp y characterp: Probar si es string, arreglo, vector (arreglo de una sola dimensión) o si es carácter. • >, = (un solo caracter), <=, >= y /= : Comparación

  32. … Predicados y Formas Condicionales • Todos los predicados pueden recibir uno o más argumentos, aplicándose sucesivamente a cada par de argumentos adyacentes. v. gr. (< 2 3 5 6 9)  T (< 2 3 5 6 6)  NIL  (< 6 6 ) es NIL Pruebas de igualdad: • (eq expS1 expS2)  T si expS1 y expS2 son el mismo objeto Lisp. No se puede usar para comparar listas, números u otros objetos. Common Lisp compara si ambos apuntadores a las expresiones son iguales. Para comparar símbolos • (eql expS1 expS2)  T si expS1 y expS2 son números del mismo tipo y valor, si son objetos representando el mismo caracter o, si la función eq aplicada a ellas devuelve T . Para comparar átomos

  33. … Predicados y Formas Condicionales • (equal expS1 expS2)  T si expS1 y expS2 evalúan a objetos Lisp equivalentes. Los objetos son equivalentes, normalmente, si sus representaciones impresas son las mismas. Sin embargo, EQUAL no compara los elementos individuales de arreglos, excepto para strings y vectores bit. EQUAL es sensible a mayúsculas y minúsculas • (equalp expS1 expS2)  T si expS1 y expS2 evalúan a objetos Lisp equivalentes, incluyendo sus expresiones - S internas Un predicado especial que aplica estas funciones es: • (member elemento lista)  T si elemento es miembro de lista (sólo en el nivel superior de ella). La función de comparación por defecto es EQL, la cual no trabaja correctamente en objetos CONS. Para utilizar EQUAL, la instrucción toma la forma • (member elemento lista :test #’EQUAL)

  34. … Predicados y Formas Condicionales • (if expS-Prueba expS-NotNull expS-IfNull) Evalúa expS-Prueba, si el resultado no es NIL (true), se evalúa expS-notNull, de lo contrario se evalúa expS-IfNull (ésta última es opcional) v. gr. (if (= x 21) (print ´BlackJack!) ) (setq x (if z ´Lista-No-Vacía´Lista-Vacía) ) • (cond (c1 e11 … e1K1) (c2 e21 … e2K2) … (c1 en1 … enKn) )  Evalúa consecutivamente las expresiones de condición ci (en orden de aparición), si alguna de ellas resulta diferente de NIL (o su sinónimo null, esto es, true), se evalúan todas las expresiones ei1 … eik correspondientes y, el último valor obtenido, es el resultado de toda la expresión cond. Las expresiones son mutuamente excluyentes, se entra a una sola rama del cond. v. gr. (setq x ( cond ( (atom milista) ´Atomo) ( (listp milista) ´Lista) ( (t ´Desconocido) )) ; Caso “default”

  35. Definición de Funciones • (defun nombre parámetros string-descripción cuerpo)  Cuando esta forma especial se evalúa, el sistema intérprete de Lisp introduce una definición de función bajo el nombre dado. El cuerpo de la función consiste de una o más formas que expresan el valor a devolver con base en los argumentos proporcionados. v. gr. ( defun cubo ( x ) “Calcula el cubo de un valor” ( * x x x ) ) • Después de que la definición se ha evaluado, se puede utilizar. v. gr. (cubo 7)  343 • string-descripción se utiliza para “documentar” la función, no afecta la ejecución de la misma, pero provee información que se puede accesar a través de la función interconstruida DESCRIBE. v. gr. (describe ´cubo)  “Calcula el cubo de un valor”

  36. … Definición de Funciones - Recursión • Recursión: Cualquier cosa o “ente”, definido en términos de sí mismo. • Recursión: Véase Recursión. Números Complejos Números Reales Números Enteros …

  37. … Definición de Funciones - Recursión • Función Recursiva: Función aplicada a un objeto complejo, definida como la combinación de resultados de aplicar la misma función a componentes del objeto complejo. • v. gr. (defun longitud ( lista ) "Devuelve el número de elementos en el nivel superior de LISTA." ( cond ( (null lista) 0 ) ( t ( 1+ (longitud (rest lista)) ) ) )) • v. gr. (defun anexar ( l1 l2 ) "Devuelve la concatenación de L2 a L1." ( cond ( (null l1) l2 ) ( t ( cons (first l1) (anexar (rest l1) l2) ) ) ))

  38. … Definición de Funciones – Recursión de Cola • Función con Recursión de Cola (Tail Recursion): Función recursiva cuya última operación consiste en la ejecución de la llamada a sí misma. • Normalmente requiere el uso de una variable “acumulador”. • Su importancia se debe a que es relativamente fácil optimizarse hacia un ciclo de repetición. • Scheme fuerza la implementación de este tipo de recursión. v. gr. (defun factorial ( n ) "Devuelve el factorial de N.“ (defun iterar (n acumula) "Devuelve el factorial de N utilizando como acumulador ACUMULA." (if (<= n 1) acumula (iterar (- n 1) (* acumula n) ) ) ) (iterar n 1) )

  39. … Definición de Funciones – Recursión de Cola La función interna ITERAR se llama a sí misma al final de su definición. Esto le permite a un intérprete o compilador reorganizar la ejecución de: 1. Trace: (FACTORIAL '5) 6. Trace: ITERAR ==> 120 2. Trace: (ITERAR '5 '1) 5. Trace: ITERAR ==> 120 3. Trace: (ITERAR '4 '5) 4. Trace: ITERAR ==> 120 4. Trace: (ITERAR '3 '20) 3. Trace: ITERAR ==> 120 5. Trace: (ITERAR '2 '60) 2. Trace: ITERAR ==> 120 6. Trace: (ITERAR '1 '120) 1. Trace: FACTORIAL ==> 120 120 A la forma más eficiente en espacio (y tiempo): 1. Trace: (FACTORIAL '5) 2. Trace: (ITERAR '5 '1) Remplazar parámetros con ('4 '5) saltar a ITERAR Remplazar parámetros con ('3 '20) re-ITERAR Remplazar parámetros con (‘2 ‘60) re-ITERAR Remplazar parámetros con (‘1 ‘120) re-ITERAR 6. Trace: ITERAR ==> 120 1. Trace: FACTORIAL ==> 120 120

  40. Variables Globales y Locales • Cada símbolo puede tener un valor global y uno local (en un momento dado) • Formas de establecer el valor global: • Macro SETF fuera del ámbito local del símbolo • Función SET (siempre accede al valor global) • Función SETQ fuera del ámbito local del símbolo • Definición de variables globales: • (defvar nombre valor-inicial string-descripcion) Un valor que se espera cambie durante la ejecución del programa • (defparameter nombre valor-inicial string-descripcion) Se espera no cambie durante una ejecución del programa (pero sí entre varias) • (defconstant nombre valor-constante string-descripcion) Inmutable, el compilador emitirá un error si se intenta modificar su valor • Por convención, el nombre de las variables globales se coloca entre ‘*’. Esto es: *mivariable*, *N*, etc.

  41. … Variables Globales y Locales (defvar *mivariable*) ; Sin valor, no puede tener string-descripción (defvar *mivariable* 5) (defvar *mivariable* 5 “Mi variable global”) (defparameter *N* 10 “Número de iteraciones”) (defconstant *raiz2* 1.4142135 “Raíz cuadrada de 2”) • Formas de acceder al valor global: • (symbol-value ´nombre-variable)  Siempre devuelve el valor global del símbolo, asumiendo que tenga uno • Evaluándose el símbolo  Esta evaluación devuelve el valor local (léxico) más interno del símbolo (si existe); de lo contrario devolverá su valor global. Si ninguno de los dos existe, se indicará un error de símbolo no ligado (a un valor)

  42. … Variables Globales y Locales • Variables Locales: • Los parámetros de una función son locales a la misma. Inclusive para funciones recursivas. • Para crear ambientes locales de variables se utilizan las formas especiales LET y LET*. • (let (vardef1 vardef2 … vardefk) expS1 expS2 … expSn) vardefi  (símbolo) y/o par (símbolo expS-valor-inicial) expSj Cuerpo de la forma especial LET • Finalizado el LET, las variables locales se eliminan de la pila • El ámbito de las variables definidas por esta forma especial se concreta exclusivamente al cuerpo de la misma (setf x 1) ; Valor global de x es 1. (let ( (x 5) ; Variable local x = 5. (y (1+ x)) ) ; Variable local y = 2 (x local no existe aún). (print (+ x y)) ; Suma x local con y local, imprime 7. (setf x 0) ; x local = 0. ) ; Devuelve 0 del LET. (print x) ; Imprime x global = 1.

  43. … Variables Globales y Locales • La forma LET* se diferencia de LET, exclusivamente, en que el inicio del ámbito de las variables locales comienza una vez declaradas éstas. En el ejemplo anterior “y” recibiría el valor 6 y no 2, por lo que la suma de “x”,“y” imprimiría 11. • Se puede aprovechar la inicialización de la forma LET* para calcular funciones más complejas de la primera variable declarada. Por ejemplo: (let* ( (x 5) (x-cuadrada (* x x)) (x-cuarta (* x-cuadrada x-cuadrada)) (f-de-x (+ (* 3 x-cuarta) (* 5 x-cuadrada) 7)) ) (print (* f-de-x 2)) ) Esta función calcula f(x) = 3x4+5x2+7, con x = 5. Finalmente multiplica por dos f(x) y devuelve un resultado de 4014. Note que sólo dos multiplicaciones binarias se utilizan para calcular x4, cuando normalmente se requieren tres (* x x x x). La forma LET* permite escribir código eficiente y fácil de leer.

  44. Ciclos de Repetición • (loop expS1 expS2 … expSk)  Evalúa repetidamente y en secuencia las expSi. La evaluación se repite indefinidamente o hasta que sea interrumpida por una instrucción RETURN. (loop (setf x (read)) (if (eql x ´exit) (return)) (setf x (cons x x)) (print x) ) • (dotimes (var count resultado) expS1 expS2 … expSk )  Evalúa la parte expresión count (que debe producir un número entero) y repite la evaluación de las expSi una vez por cada valor (asignado a la variable var), desde 0 al entero calculado menos 1. Al finalizar, el resultado de evaluar la expresión result (si existe) se devuelve. (let (potencias-de-2 potencias-de-3) (dotimes (i 10 (list potencias-de-2 potencias-de-3)) (setf potencias-de-2 (append potencias-de-2 (list (expt i 2)))) (setf potencias-de-3 (append potencias-de-3 (list (expt i 3)))) ) (print potencias-de-2) (print potencias-de-3) )

  45. … Ciclos de Repetición • (dolist (var lista-valores resultado) expS1 expS2 … expSk )  Evalúa las expSi una vez por cada asignación a var de un elemento de los valores de lista-valores. Al finalizar, el resultado de evaluar la expresión result (si existe) se devuelve. En cada repetición del ciclo se realizan las operaciones: (setf var (car lista-valores)) y (setf lista-valores (cdr lista-valores)) (let ((x nil)) (dolist (stack ´(a b c) x) (push stack x) ) (print x) )

  46. Funciones de Orden Superior • Funciones que pueden tener como argumentos otras funciones, y que también pueden devolver funciones como resultado. Por ejemplo, en matemáticas las funciones de derivación y/o integración son de orden superior. • (eval expS)  El intérprete de Lisp evalúa expS y, posteriormente, realiza una evaluación extra. Esto es útil para evaluar formas que son construidas en tiempo de ejecución. (setf max '(if (> arg1 arg2) arg1 arg2) ) (print “Dato1? ” ) (setf arg1 (read)) (print “Dato2? ” ) (setf arg2 (read)) (setf x (eval max)) ; Evaluar max en tiempo de ejecución

  47. … Funciones de Orden Superior • (funcall nombre-función a1 a2 … ak)  Aplica el valor de nombre-función (un símbolo al que se le ha asignado el nombre de una función), a los argumentos ai. (print "Dato1? " ) (setf arg1 (read)) (print "Dato2? " ) (setf arg2 (read)) (print "Qué operación aplico (+ ó -)? " ) (setf f (read)) (setf x (funcall f arg1 arg2)) • Muy útil cuando no se conoce en tiempo de compilación la función a aplicar. • La función a ejecutar NO debe ser una forma especial o de macro. • El número de argumentos dados a funcall debe coincidir con el número de parámetros que recibe la función a invocar indirectamente.

  48. … Funciones de Orden Superior • (apply nombre-función A1 A2 … Ak lista-argumentos)  Idéntica a funcall, pero se utiliza cuando el número de argumentos no se conoce anticipadamente. • nombre-función se aplica a la lista obtenida de la concatenación de los argumentos Ak (si existen) y lista-argumentos. (print "Lista de argumentos? " ) (setf arg1 (read)) (print "Qué operación aplico (+ ó -)? " ) (setf f (read)) (setf x (apply f arg1)) • El último argumento dado a apply, siempre debe ser una lista. • Igual que para funcall, la función a ejecutar NO debe ser una forma especial o de macro. En tal caso se debe utilizar eval.

  49. … Funciones de Orden Superior • nombre-función también puede ser un objeto funcional devuelto por una llamada a la función function. (print "Lista de argumentos? " ) (setf arg1 (read)) (setf x (apply (function +) arg1)) • Debido a su uso frecuente, existe una abreviatura para FUNCTION, igual que para QUOTE y '. Esta es #'. (print "Lista de argumentos? " ) (setf arg1 (read)) (setf x (apply #'+ arg1))

  50. Expresiones LAMBDA • Especifican funciones en un programa de Lisp, sin la necesidad de darles o llamarlas por nombre. • Proporcionan idea de “localidad”, haciendo más fácil entender el código, ya que la función se encuentra donde se utiliza. • (lambda lista-argumentos cuerpo) La función f(x) = x2 + 2y  (lambda (x y) (+ (* x x) (* 2 y))) • Las expresiones lambda se utilizan más comúnmente como argumentos de APPLY. (print "Dato? " ) (setf arg1 (read)) (setf x (apply (function (lambda (y) (* y y y))) (list arg1))) • En el ejemplo anterior, la forma especial FUNCTION sirve para evitar que la expresión LAMBDA sea evaluada.

More Related