Resumen de LISP Javier Gil Julio, 2011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; conceptos fundamentales de Lisp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; sintaxis basica ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (+ 2 3) (* 2 (+ 4 6)) (+ 2/7 7/67) (/ #c(2 3) 6/4) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; operadores matematicos basicos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (+ 2 3) (- 8 6) (* 2/7 6/5) (/ 4 5) (exp 9) (expt 2 4) (sqrt 11) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; operaciones basicas con listas ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; creacion de una lista con (cons ) (cons 3 nil) ; insercion de un nuevo elemento (cons 4 (cons 3 nil)) ; creacion de una lista con varios elementos con (list ) (list 1 2 3 4) 1 ; primer elemento y resto de una lista (first ’(1 2 3 4)) (rest ’(1 2 3 4)) ; creacion de una variable tipo lista (setq a ’(1 2 3 4)) (first a) (rest a) ; elemento enesimo de una lista (nth 3 a) ; listas como conjuntos (union ’(1 2 3) ’(3 4 5)) (intersection ’(1 2 3) ’(2 3 7)) ; concatenar listas (concatenate ’list ’(1 2 3) ’(4 5 6)) ; tambien con vectores (concatenate ’vector (make-array ’(5)) (make-array ’(3))) ; obtener sublista de una lista (subseq ’(yo tu el nosotros vosotros ellos) 1 3) ; invertir el orden de una lista (reverse ’(yo tu el nosotros vosotros ellos)) ; longitud de una lista (length ’(1 (2 3) 4 ())) ; contar apariciones de un elemento en una lista (count 3 ’(1 2 3 4 5 3)) ; contar elementos que cumplen una condicion (count-if #’evenp ’(1 2 3 4 5 6)) ; contar elementos que no cumplen una condicion (count-if-not #’evenp ’(1 2 3 4 5 5)) ; usar como condicion una funcion lambda (count-if #’(lambda (n) (< n 3)) ’(1 2 3 4 5)) ; puede indicarse un rango (count 3 ’(1 3 3 3 4 3 5) :start 1 :end 4) ; rellenar (fill ’(1 2 3 4) 6) (fill ’(1 2 3 4) 6 :start 0 :end 3) 2 ; etc. Lamkins, cap. 13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; variables locales ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (let ((c 2) (b 3)) (+ c b)) (let* ((c 2) (z (+ c 5)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; estructuras de control ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; (if <condicion> <then> <else>) ; <then> y <else> son una unica expresion ; una serie de expresiones se introduce ; mediante (progn ) (if (< a 2) (+ a 3) (- a 9)) (if (< a 2) (+ a 2) (progn (- a 9) (print "hola"))) ; if multiple con (cond ) ; (cond (<condicion> <accion>) ; (<condicion> <accion>) ; (t <accion>) ; (cond ((> a 2) (* a 5)) ((< a 2) (/ a 9)) (t (+ a 1))) ; if que carece de <else> con (when ) (when (> a 9) (print a)) ; iteracion con do ; (do ((<var> <inicial> <actualizacion>) (<var> <inicial> <actualizacion>) ... ) (<condicion salida><retorno>) ; <instrucciones> ; ) (do ((n 1 (+ n 1))) ((> n 10) ’hecho) (print n)) ; iteracion con dotimes, el valor inicial es 0 ; (dotimes (<var> <max>) ; <instrucciones> ; ) (dotimes (n 10) (print n)) 3 ; iteracion con dolist ; (dolist (<var> <lista>) <instrucciones>) (dolist (x ’(1 2 3)) (print (* x 2))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; bloques ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; progn permite incluir una serie de listas para ejecucion secuencial ; suele usarse con (if ) (progn ()()()... ) ; block es similar a progn, pero con un identificador y la posibilidad ; de salir inmediatemente (block zafiro (format t "La vida es bella") (return-from zafiro ’esmeralda) (format t "aqui nunca se llegara")) ; para salir de una funcion anidada con otra u otras, se usa ; la pareja ’catch-throw’ (defun super () (catch ’aqui (sub))) (defun sub () (throw ’aqui 99) (format t "aqui nunca se llegara")) > (super) 99 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; funciones ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ^ (x y) (if (< y 2) x (* x (^ x (- y 1))))) (defun fct (n) (if (< n 2) 1 (* n (fct (- n 1))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; funciones de orden superior ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; paso de argumentos a una funcion mediante una lista (apply #’+ ’(1 2 3 4)) ; otra version de lo mismo (funcall #’+ 1 2 3) (funcall #’+ 1 2 ’(3 4)) ; aplicacion de una funcion sobre los elementos de una lista (mapcar #’not ’(nil t nil t)) 4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; argumentos opcionales llamando a funciones ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; puede pasarse a una funcion un numero variable de argumentos ; &rest indica una variable que recolecta en una lista a partir ; de un punto el resto de argumentos que se pase a la funcion (defun filosofo (cosa &rest x)(list cosa ’es x)) (filosofo vida ) ; &optional indica que los parametros que vienen a continuacion ; son opcionales, y por defecto estan a nil, salvo que se diga ; lo contrario (defun una-suma (a b &optional (c 0)) (+ a b c)) ; tambien pueden declararse claves, que pueden estar o no ; y que por defecto son nil (defun otra-suma (a b &key (c 0))(+ a b c)) (otra-suma 2 3) (otra-suma 2 3 :c 5) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; macros ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; una macro es un programa que crea un programa, que despues ; es ejecutado. ; funcion para hacer una tabla de valores de la funcion x^2 (dotimes (n 11) (print n) (prin1 (* n n)) ; macro para hacer una tabla de valores de _cualquier_ funcion ; la ’‘’ precede al programa, y una ’,’ antes de un parametro ; indica que ese parametro ha de ser sustituido por el argumento ; de la macro (defmacro tabla (f desde hasta) ‘(do ((n ,desde (+ n 1)))((> n ,hasta)) (format t "~&~4D ~16D" n (funcall #’,f n)))) (tabla fct) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; matrices ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; creacion de una matriz (setq a (make-array ’(3 3))) 5 ; creacion de una matriz indicando valor inicial (setq m (make-array ’(3 3) :initial-element 0)) ; acceso a un elemento (setf (aref a 1 2) 9) (print (aref a 1 2)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; estructuras con (defstruct ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; crear una estructura (defstruct coche marca modelo motor) ; defstruct acaba de crear funciones para ; crear variables de tipo coche y para acceder ; a sus campos ; crear sin valores iniciales (setq m (make-coche)) ; crear con valores iniciales (setq m (make-coche :marca "mercedes" :modelo "c220cdi" :motor "D4L")) ; accede a un campo (setf (coche-marca m) "toyota") (print (coche-marca m)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; diccionarios (hash) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; crear una tabla (setq h (make-hash-table)) ; crear una tabla que use numeros como clave (make-hash-table :test #’eql) ; crear una tabla que use listas como clave (make-hash-table :test #’equal) ; consultar si existe una clave (gethash ’24229915 h) ; introducir una nueva pareja (setf (gethash 24229915 h) "javier gil") (setf (gethash 23445788 h) "rosa fuentes") 6 ; eliminar una pareja (remhash 24229915 h) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; cadenas de caracteres ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; una cadena es un vector de caracteres (setq a "hola chaval") ; y por tanto se puede acceder con (aref ) a sus elementos ; que se indexan desde 0 (aref a 3) ; y equivale a (char a 3) ; existe operadores especializados para caracteres: ; char=, char<, char>, char/= ; pero las cadenas tambien son secuencias (concatenate ’string "hola " "mundo") ; aunque en a (subseq ) no es preciso decirle que se trata de ; una cadena (subseq "hola mundo" 0 4) ; hay muchas funciones que trabajan con cadenas, asi ; como operadores relacionales especializados ; string=, string<, string>, string/= (setq a " Esto es una prueba ") (string-capitalize a) (string-downcase a) (string-upcase a) (string-upcase a :start 3 :end 7) (setq b "-----Hola-----") (string-left-trim "-" b) (string-right-trim "-" b) (string-trim "-" b) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; entradas con (read) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; (read ) lee caracteres de la entrada y compone objetos validos ; lisp (defun leer-numero () (let (a) (setq a (read)) (if (numberp a) a (leer-numero)))) 7 ; hay versiones especializadas para leer cadenas y caracteres (read-char) (read-line) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; salidas con (format) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; format toma como argumentos un destino, una cadena ; de formato y una serie de argumentos para sustituir en ; la cadena de formato (format t "~&~A" 23) ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Secuencia Accion -------------------------------------------------------~& inserta nueva linea, slo si el cursor no se encuentra ya en la primera columna ~% inserta nueva linea ~T tabulador ~| nueva pagina ~D entero base 10 ~B entero binario ~X entero hexadecimal ~O entero octal ~bR entero en base ’b’ ~F punto flotante ~E notacion cientifica ~G ~F o ~E segun magnitud ~A formato legible para el usuario ~S formato legible para (read ) ~@R numeros romanos ; puede iterarse sobre los elementos de una lista (format t "~&Nombre~20TCodigo~{~&~A~20T~A~}" ’("javier" 24 "rosa" 15)) ; puede justificarse en un campo, a la izquierda o a la derecha (format t "~20D~-20D" 16 16) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; apertura y cierre de archivos ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; un archivo se abre con open (setq corriente-de-salida (open "temporal" :direction :output)) ; se escribe con print o format (print ’abc corriente-de-salida) 8 ; y se cierra con close (close corriente-de-salida) ; ejemplo: escribir a archivo una tabla de valores ; y luego recuperarla en una matriz (setq m (make-array ’(10 2))) (setq salida (open "temporal" :direction :output)) (do ((n 1 (+ n 1)))((> n 10))(format salida "~&~4D~10D" n (* n n n))) (close salida) (setq entrada (open "temporal" :direction :input)) (do ((n 0 (+ n 1)))((> n 9)) (setf (aref m n 0) (read entrada)) (setf (aref m n 1) (read entrada))) 9