LISP (List Processing) El lenguaje lisp está compuesto por dos cosas principalmente: Átomos Pueden ser de dos tipos: – Símbolos (Identificadores): Estos átomos comienzan con un caracter seguido de cualquier otro caracter excepto espacios, comas, puntos o paréntesis. Ejemplo: casa, ca&, casa1, C, etc. – Números: Todos los números que se conocen Ejemplos: 1,2,3,etc. Existen palabras reservadas que no pueden considerarse dentro de este tipo de datos a los cuales se le llama átomos especiales: T y nil, éstos son átomos reservados, que representan a verdadero y falso respectivamente, por otra parte nil también representa una lista vacía. También se consideran átomos especiales a las funciones predeterminadas de lisp como son: cdr, cons, list, append, entre otros, los cuales no pueden usarse como identificadores. En lisp las mayúsculas y las minúsculas son iguales, por tanto un átomo hola y otro HoLa es lo mismo. Listas La lista es el elemento principal del lenguaje Lisp, pues absolutamente todo es representado mediante listas de ahí el nombre List Processing, también se le conoce como lenguaje entre paréntesis. Las listas son datos que representan secuencias de átomos o de otras listas separadas por un espacio, todos estos contenidos dentro de un paréntesis, cabe indicar que las listas pueden ser vacías en cuyo caso se representan con nil o () Ejemplos: (a b casa 5 &), (a (b casa) 5 &) FUNCIONES PRIMITIVAS Operadores Para las diferentes operaciones aritméticas el formato es el siguiente: Formato: (operador argumento1 argumento2 … argumentoN) Suma ‘+’ (+ 3 5 10) → 18 (+ 10 14 20) → 44 Resta ‘-’ (- 3 10) → -7 (- 20 15) → 5 Multiplicación ‘*’ (* 2 3 4) → 24 (* 10 5) → 50 División ‘/’ (/ 45 9) → 5 (/ 125 5) → 25 Valor Absoluto (abs -6) → 6 (abs 10) → 10 Raiz (sqrt 144) → 12 (sqrt 169) → 13 Operaciones combinadas (+ (* 3 2) (- 10 2)) → 14 (/ (+ 12 3) (sqrt 25)) → 3 Operaciones en Lips CL-USER 33 : 4 > (+ 0.18 (* 2 1600) (* 3 2000)) 9201.18 CL-USER 34 : 4 > (* 0.18 (+ (* 2 1600) (* 3 2000)) 10856.0 CL-USER 29 : 4 > (+ 9200 (* 0.18 9200)) 10856.0 ASIGNACIÓN DE VALORES DE ÁTOMOS Si queremos asignar valores una variable o un átomo en lisp se hace de la siguiente manera: (SET ‘edad 23) La palabra reservada SET es una función que asigna el valor 23 al átomo edad, que se debe llevar un apóstrofe delante (quote), caso contrario el resultado será error. Esta forma de asignar hace que se tenga que quotear, cosa que se resuelve asignando mediante la función SETQ de la forma siguiente: (SETQ edad 23) Como vemos en este segundo caso ya no es necesario poner el apóstrofe (quote). Por otra parte también existe para asignar variables globales: (SETF edad 23) Asigna el valor a la variable (y la crea si no existe), regresa el valor asignado. CONSTRUYENDO LISTAS CONS La función cons añade un elemento al inicio de una lista existente. Formato : (cons Elemento (Lista)) -> (Elemento Lista) Elemento puede ser un átomo o una lista que se añade a Lista, como resultado se obtiene la lista con el elemento agregado. Ejemplos: (cons ‘perro ‘(gato conejo)) -> (perro gato conejo) (cons 2 ‘(4 6 8)) -> (2 4 6 8) (cons ‘a ‘(e i o u)) -> (a e i o u) LIST La función lista crea una lista con los elementos declarados. Formato : (list Elemento1 Elemento2 … ElementoN) -> (Elemento1 Elemento2 … ElementoN) Se pueden ingresar N Elemento que pueden ser átomos o listas, como resultado se obtiene una listas con los N Elementos. Ejemplos: (list ‘luna ‘sol ‘estrella) -> (luna sol estrella) (list ‘manzana ‘(zanahoria apio)) -> (manzana (zanahoria apio)) (list nil ‘rojo) -> (nil rojo) APPEND Une varias listas en una sola. Formato : (append (Lista1) (Lista2) … (ListaN)) -> (Lista1 Lista2 … ListaN) Se pueden ingresar N Listas, como resultado se obtiene una Lista conformada por los elementos de las N Listas. Ejemplos: (append ‘(1 3 5) ‘(2 4 6)) ->(1 3 5 2 4 6) (append ‘(rojo azul) ‘(amarillo verde)) -> (rojo azul amarillo verde) TOMAR VALORES DE UNA LISTA CAR La función car obtiene el primer elemento de una lista, ya sea un átomo o una lista. Formato: (car Lista) Ejemplos: (car ‘(a b c d)) -> a (car ‘((12 13 14) (21 22 23))) -> (12 13 14) (car ‘((brasil paraguay))) ->(brasil paraguay) CDR La función cdr devuelve una lista sin el primer elemento de esta, ya sea un átomo o una lista. Formato (cdr Lista) Ejemplos: (cdr ‘(a b c d)) -> (b c d) (cdr ‘((12 13 14) (21 22 23))) -> ((21 22 23)) (cdr ‘((brasil paraguay))) ->nil Operaciones combinadas con listas en Lips: CL-USER 20 : 4 > (cons 't (cdr (car '((36 48 29) 45)))) (T 48 29) CL-USER 21 : 4 > (cons 't (car (list (cdr '(36 48 29)) '45))) (T 48 29) CL-USER 22 : 4 > (list 'jun 'jul (car (car '((ene feb mar abr))))) (JUN JUL ENE) CL-USER 23 : 4 > (append (car '((1 3) 5)) '(7 9)) (1 3 7 9) COMILLA Y COMA La comilla ('), la letra q en setq y la función "quote" se utilizan en LISP para distinguir explícitamente entre expresiones evaluadas. Esta distinción se necesita debido a la naturaleza dual de un símbolo en LISP en algunos contextos: su uso como un ítem de dato y su uso como un nombre de variable. (list 'd '1 (/ 3 45) 'b '4)=> (d 1 15 b 4) Ejemplos: (list 'rama (list 'e 'r) 'r )=> (rama e r r) (list 'r 'e (* 5 6) 'p 'q)=> (r e 30 p q) (list 'w (list '4 '5) (+5 3) 'h 'i)=> (w 4 5 8 h i) IGUALDAD Existen 2 tipos de igualdad. Ejemplo: Usando eq (eq 'x 'x) => T (equivalente a un resultado verdadero) (eq 'a 'b) => nil ( equivalente a un resultado falso) (eq '(a) '(a)) => nil Usando equal (equal 'x 'x) => T (equivalente a un resultado verdadero) (equal '(a) '(a)) => T (equal '(or p q) '(or p q)) => T Más Ejemplos: (eq 'w 'w) => T (eq 'q 'a) => nil (eq '(e) '(e)) => nil (equal 'a 'a) => T (equal '(j) '(j)) => T (equal '(or r j) '(or r j)) => T (eq 'n 'n) => T (eq 's 'r) => nil (eq '(r) '(r)) => nil (equal 'j 'j) => T (equal '(b) '(b)) => T (equal '(or b c) '(or b c)) => T (equal x y) es T cuando (eq x y) es verdadero y cuando las cosas lucen igual son verdaderos (del mismo tipo). CONJUNTOS Se pueden tratar a las listas como conjuntos (el orden no es preservado), es decir pueden haber listas dentro de otras lista. A esta agrupación de listas se les llama conjuntos, si algún valor se repite se coloca una sola vez en el conjunto. (union '(x y) '(x z)) => (x y z) (union '((a) (b)) '((a))) => ((a) (b) (a)) (union '((a) (b)) '((a)) :test #'equal) => ((a) (b)) Ejemplos: (union '(p e) '( r r o)) => (p e r o) (union '((u)(n)) '((u))) => ((u) (n) (u)) (union '((p) (q)) '((p)) :test #'equal) => ((p) (q)) La evaluación de la condición para determinar si 2 ítems en el conjunto son iguales es la función igual. (adjoin 'a '(a b c)) => (a b c) (set-difference '(a b c) '(b d c)) => (a) Ejemplos: (adjoin 'i '(i e)) => (i e) (set-difference '(j e f f e r) '(j e f i t o)) => (r) (adjoin 'o '(r o s a)) => (r o s a) (set-difference '(i c a) '(t i a)) => (c) Los comandos adjoin y set-difference pueden usar: test #'equal. Pueden incluso proveer su propia función (una vez que nosotros mostremos como definir una)