You are on page 1of 9

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)

; 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)

; 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))

; 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)))

; 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")

; 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))))

; 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)

; 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)))