Anda di halaman 1dari 16

TUTORIAL DE LISP

Como primer ejemplo se tiene las siguientes líneas de comandos en LispWords:

• CL-USER 4 : 1 > (+ 24 35 67)


126

Ésta notación es bastante usada, como se ve el resultado del comando ingresado (+ 24 35 67) es 126.

TIPOS DE DATOS

• Atoms: x, 20, m , n , nil, T


Evaluar un atom da el valor asignado a este, es necesario asignarle un valor a las variables en caso
contrario saldrá un error; pero en el caso de los números no necesitan ser asignados porque ellos
mismos se evalúan.

o CL-USER 1 > 29

29

o CL-USER 2 > z

Error: The variable Z is unbound.

Para asignar valores a los atoms se utiliza los comandos setq o setf. En el siguiente ejemplo
asignaremos los números 17 y 19 a los atoms m y n respectivamente:

o CL-USER 1 > (setq m 17)


17
o CL-USER 2 > (setf n 19)
19

Los atoms reservados son:

o CL-USER 3 > nil


NIL
o CL-USER 4 > t
T

Además mNp es el mismo atom que MNP

• Lists: (x), (+ 3 6 8), (a (b c) d), (), nil


Para evaluar una lista se invoca a una función, de la forma siguiente: (function-name arg1 … argn).
Por ejemplo:

o CL-USER 5 > (+ 54 23 12)


89
o CL-USER 6 > (/ 20 5)
4
o CL-USER 7 > (sqrt 36)
6.0

También podemos invocar una función evaluando una lista en donde uno de sus argumentos es un
Atom con un valor previamente asignado.

o CL-USER 8 > (setq a 13)


13
o CL-USER 9 > (- 45 a)
32

NIL es un Atom y una List, su valor es vacío.

FUNCIONES PRIMITIVAS

Lips incluye algunas funciones adicionales como: +, -, *, /, max, min, sqrt.

Más importante aún, incluye operaciones de construcción de listas:

 Cons:
Construye una lista a partir de datos y una cola. Y el valor de la cola significa nada; es decir, NIL.

o CL-USER 1 > (cons 5 nil)


(5)
o CL-USER 2 > (cons 14 (cons 7 nil))
(14 7)
o CL-USER 3 > (cons 9 (cons 11 (cons 13 nil)))
(9 11 13)

Al usar cons con un Atom que no es reservado producirá un error, para que no ocurra esto se tiene que
utilizar apóstrofes (`).

o CL-USER 4 > (cons m nil)


Error: The variable M is unbound.
o CL-USER 5 : 1 > (cons `m nil)
(M)

También puede ser aplicado a una lista completa; pero esto puede resultar complicado, para ello es
mejor usar un list o un append.

o CL-USER 10 : 2 > (cons `x `(y w z o p))


(X Y W Z O P)

 List y Append:
Son funciones que toman cualquier cantidad de argumentos. En Append es necesario que al declarar
los argumentos vayan entre paréntesis si son 2 o más argumentos, mientras que en el list solo es
necesario cuando algunos de sus argumentos tienen 2 o más elementos.

o CL-USER 14 : 4 > (list `a)


(A)
o CL-USER 15 : 4 > (append `a)
A
o CL-USER 11 : 2 > (list `m `n `o `p)
(M N O P)
o CL-USER 22 : 6 > (append `(b) `(c) `(d))
(B C D)
o CL-USER 18 : 5 > (append `(a b) `(c d ))
(A B C D)
o CL-USER 23 : 6 > (list `(b) `(c) `(d))
((B) (C) (D))
o CL-USER 24 : 6 > (list `m `(o p q) `(r s t))
(M (O P Q) (R S T))
Si uno de sus argumentos es una operación no es necesario usar el apóstrofe

o CL-USER 1 > (list `p `q 1 (sqrt 25) 20)


(P Q 1 5.0 20)
o CL-USER 2 > (setq var1 12)
12
o CL-USER 3 > (setf var2 11)
11
o CL-USER 4 > (list (+ var1 var2) `b (- var1 10) `c (* var2 2) 30)
(23 B 2 C 22 30)

De manera reducida, usando el apóstrofe y la coma podemos evitar usar el list y el apóstrofe repetidas
veces:

o CL-USER 5 > `(25 m ,(* var1 var2) p 2)


(25 M 132 P 2)
o CL-USER 6 > `(12 ,(+ 1 2) p ,(* var1 2))
(12 3 P 24)

 Accesando a la lista:
 First y car nos dan el primer elemento de la lista, si la lista no es NIL; caso contrario devolverá NIL.

o CL-USER 7 > (first `(m n p q))


M
o CL-USER 8 > (first `((m n p) q r s))
(M N P)
o CL-USER 9 > (first `(x w (y z)))
X

 Last devuelve el último elemento de la lista, si la lista es nil devuelve NIL.


o CL-USER 10 > (last `(1 2 3 4 5 6))
(6)
 Rest y cdr devuelven el resto, es decir todo menos el primer elemento de la lista, si la lista no es
NIL; caso contrario devolverá NIL.
o CL-USER 14 > (rest `(w x c z))
(X C Z)
o CL-USER 16 > (cdr `(m n (o p)))
(N (O P))

 Car y cdr pueden combinarse para obtener diferentes resultados, la manera de trabajar es de
derecha a izquierda.

o CL-USER 19 > (cadr `((a b c) d e f))


D
o CL-USER 26 : 4 > (caar `((m n p) q r))
M
o CL-USER 27 : 4 > (cddr `((x y) z (w m n)))
((W M N))
o CL-USER 28 : 4 > (cdar `((m n o p) (x y) z))
(N O P)

 Cambiando los valores de los Atoms:


Ejemplo:
o CL-USER 3 > (setq x '(m n (b c)))
(M N (B C))
o CL-USER 4 > (cons 'a x)
(A M N (B C))
o CL-USER 5 > x
(M N (B C))

Como se ve al utilizar setq el valor del Atom X no cambia. También se tiene setf que es un tipo de setq
que toma como primer argumento una función.

o CL-USER 10 : 2 > (setq x '((a b c) d e (f)))


((A B C) D E (F))
o CL-USER 11 : 2 > (setf (cadr x) 20)
20
o CL-USER 12 : 2 > x
((A B C) 20 E (F))
 Equality:
Hay 2 tipos de igualdades:
1. (eq x y) Compara 2 argumentos simples X e Y, dando como resultado T si es que son iguales o NIL
en caso contrario.

o CL-USER 17 : 2 > (eq 'm 'm)


T
o CL-USER 18 : 2 > (eq 'm 'n)
NIL
o CL-USER 19 : 2 > (eq '(m) '(m))
NIL

2. (equal x y) Compara 2 argumentos que pueden ser listas, dando como resultado T si es una
igualdad o NIL en caso contrario.
o CL-USER 20 : 2 > (equal '(m) '(m))
T
o CL-USER 21 : 2 > (equal 'm 'm)
T
o CL-USER 22 : 2 > (equal '(m n p q r) '(m n p q r))
T
 Sets:
Se puede manejar las listas como conjuntos.
o CL-USER 25 : 2 > (union '(m n p q r) '(p q r s t))
(T S M N P Q R)
o CL-USER 26 : 2 > (union '((a (b c))) '((d (b c))))
((D (B C)) (A (B C)))
o CL-USER 30 : 2 > (union '((a) (b) (c) (d)) '((d)) :test #' equal)
((A) (B) (C) (D))

Se coloca la siguiente sentencia: test #' equal para evaluar las listas de los argumentos y suprimir las
listas repetidas.

Adjoin y set-difference son usados para añadir un elemento o una lista a otra lista y para separar los
elementos que diferencia a un argumento del otro, respectivamente. En caso de este último es similar
a la propiedad de diferencia estudiada en conjuntos.
o CL-USER 35 : 6 > (adjoin '(a b) '(c d e))
((A B) C D E)
o CL-USER 36 : 6 > (set-difference '((a b) c) '(c))
((A B))

Con Adjoin y set-difference tambien se puede usar: test #' equal.

 Más funciones:
 length Devuelve el número de elementos de la lista

o CL-USER 4 > (length `(m (n (o p)) (q r)))


3
o CL-USER 5 > (length `(a b (c d e)))
3

 Atom Devuelve T si el argumento es atom sino devuelve NIL, por ejemplo:

o CL-USER 6 > (atom `x)


T
o CL-USER 8 : 1 > (atom `( xy z w))
NIL

 listp devuelve T si el argumento es una lista sino devuelve NIL.

o CL-USER 10 : 2 > (listp `(m n))


T
o CL-USER 11 : 2 > (listp `(x))
T
o CL-USER 13 : 3 > (listp `x)
NIL

 Representando sentencias KIF:


Tenemos las siguientes sentencias:

 (=> m (or n p))


 (not (not (and a b))
La forma de representar las sentencias KIF en Lisp es usando listas. Los operadores KIF (=>, <=, <=>, or,
and, not) siempre serán el primer elemento de la lista, así tenemos:

o CL-USER 16 : 3 > (list ‘=> ‘m (list ‘or ‘n `p))


(=> M (OR N P))
o CL-USER 19 : 5 > (list ‘not (list ‘not (list `and `a `b)))
(NOT (NOT (AND A B)))

DEFINIENDO FUNCIONES

Al igual que otros lenguajes de programación, en Lisp podemos declarar funciones para modularizar los
programas y hacerlos más legibles en la medida de lo posible, reutilizando así código escrito y separando
distintas partes del problema a representar en módulos.

Las funciones se definen de la siguiente manera:

(defun <name> <documentation-string>(<arguments>) <body>)


Ejemplos:

o CL-USER 3 > (Defun suma(a b) (+ a b))


SUMA

RAMIFICACIÓN

• (if <expr> <then-expr> <else-expr>)

o CL-USER 5 : 1 > (setq a 1)


1
o CL-USER 6 : 1 > (setq b 1)
1
o CL-USER 8 : 2 > (if (= a b) (+ a 1) (- a 1))
2
• La palabra cond ejecuta un flujo de control dependiendo de la condición si es cierta o no. Es algo
parecido al switch de C /C++ , Java, C# .NET , etc... Pero con la diferencia que en este caso lo que se
pone en los case son condiciones lógicas y no constantes.

(cond ((testa) (form1a) (form2a)…


(formNa))((testb) (form1b)…(formNb)) …
(t (form1k) … (formNk))

o CL-USER 5 : 2 > (setq n 8)


8
o CL-USER 6 : 2 > (cond ((< n 5) ’suspenso)
((< n 7) ’aprobado)
((< n 9) ’notable)
(t ’sobresaliente))
NOTABLE

FUNCIONES LÓGICAS Y NULL

Se tiene las siguientes funciones lógicas:

• (and <form1> <form2> … <formn>)


Se evalúa como nil siempre que <formi> sea NIL, de lo contrario se evalúa como <formn>.

o CL-USER 2 : 1 > (and 'a nil)


NIL
o CL-USER 3 : 1 > (and 'a 'b)
B

• (or <form1> <form2> … <formn>)


Se evalúa el primer argumento no nulo, si no hay ninguno evalúa a NIL.

o CL-USER 5 : 1 > (or 'a 'b)


A
o CL-USER 6 : 1 > (or 'a nil)
A
• (not <form>) and (null <form>) are identical.
Usualmente se aplica cuando el resultado debe ser una lista.
Evalúa como T si <form> es NIL, por ejemplo:

o CL-USER 22 : 2 > (not (listp '(a b c)))


NIL
o CL-USER 24 : 2 > (not (listp 'a))
T

ITERACIÓN

• (let ((<var1> <init1>) (<var2> <init2>) …)


<body> )
Esta función permite asignar variables locales antes de usarlas.

o CL-USER 4 > (let ((a 15) (b 13)) (* a b))


195
• (dotimes (<counter> <limit> <result>)
<body>)
DOTIMES evalúa la forma del cuerpo N veces cambiando su índice de 0 a N-1 y regresando
resultado (NIL si no se especifica).

o CL-USER 5 > (dotimes (i 5) (print i))


0
1
2
3
4
NIL
• (dolist (<var> <initlist> <result) <body>)
Es parecido al DOTIMES pero cambia su variable sobre los elementos de una lista.

o CL-USER 6 > (dolist (x '(5 8 10)) (print (* x 3)))


15
24
30
NIL
• (do ((<var1> <init1> <increment1>)
(<var2> <init2> <increment2>) …)
(<termination-test> <result>)
<body>)

DO es el iterativo más poderoso de LISP. Permite asignar varias variables (como LET), hacer pasos de
iteración como uno quiera y especificar la condición de terminación.

o CL-USER 13 : 3 > (do ((n 1 (+ n 1))) ((> n 10) 'hecho) (print n))

10

HECHO

RECURSIÓN

Por ejemplo:

o CL-USER 19 : 4 > (defun factorial (n)


(if (= n 0)
1
(* n (factorial (- n 1)))))
FACTORIAL
o CL-USER 20 : 4 > (factorial 8)
40320

LAMBDA

((LAMBDA (var1...varN) (s1...sM)) val1...valN)

En este caso var1 var2… varN son las variables a las cuales se les asigna un valor respectivo que vienen a ser
val1 val2… valN las cuales evalúan las expresiones presentes en s1 s2… sN para generar un resultado.

o CL-USER 24 : 6 > ((lambda (m n) (* m n)) 5 8)


40

MAPCAR

(mapcar <function-name> <list>)

Mapcar aplica la función a cada elemento de la lista y devuelve una lista de resultados.

o CL-USER 1 > (mapcar #'(lambda (m) (* 3 m)) '(3 5 7))


(9 15 21)

MEMBER
Comprueba si un elemento pertenece a una lista y devuelve una lista con los elementos que hay desde el
elemento coincidente.

o CL-USER 5 : 2 > (member 'c '(b c a))


(C A)

OUTPUT
(print <form>)
Evalúa <form> y devuelve el elemento evaluado por pantalla.
o CL-USER 2 > (print (/ 258 4))
129/2
129/2
Princ, print1, print, todos estos trabajan básicamente de la misma forma, salvo pequeñas diferencias.
FORMATTED OUTPUT (Salida con formato)
(format <destination> <control-string> <optionalarguments>)

Algunas directivas de la función FORMAT:


 ~a escribe el siguiente argumento
 ~& comienza nueva línea, si no está al comienzo de una
 ~% comienza nueva línea
 ~Na escribe el siguiente argumento más los espacios suficientes para ocupar N caracteres de
ancho
 ~D Número decimal
 ~~ tilde

EJEMPLO:

o CL-USER 4 > (format t "~&El cuadrado de ~a es ~a" 3 (* 3 3))


El cuadrado de 3 es 9
NIL
o CL-USER 5 > (setf l ’(a b c))
(A B C)
o CL-USER 6 > (format t "~&La longitud de la lista ~a es ~a" l (length l))
La longitud de la lista (A B C) es 3
NIL

DEBUGGING: TRACE

(trace <func-name1> <func-name2> … <funcnamen>)

Cada vez que una de estas funciones es evaluada, Lisp imprime el nombre de la función y los argumentos
que da el terminal, cada vez que una de estas funciones existe, Lisp imprime el valor que regresa.

Haciendo una traza (trace) podemos ver que ocurre hasta que salga el resultado. Por ejemplo:
o CL-USER 3 : 1 > (defun factorial (n)

(if (eq n 0)

(* n (factorial (- n 1)))))

FACTORIAL

o CL-USER 5 : 1 > (trace factorial)

(FACTORIAL)

o CL-USER 7 : 1 > (factorial 4)

0 FACTORIAL > ...


>> N : 4
1 FACTORIAL > ...
>> N : 3
2 FACTORIAL > ...
>> N : 2
3 FACTORIAL > ...
>> N : 1
4 FACTORIAL > ...
>> N : 0
4 FACTORIAL < ...
<< VALUE-0 : 1
3 FACTORIAL < ...
<< VALUE-0 : 1
2 FACTORIAL < ...
<< VALUE-0 : 2
1 FACTORIAL < ...
<< VALUE-0 : 6
0 FACTORIAL < ...
<< VALUE-0 : 24
24
Para desactivar el rastreo de una función utilizamos untrace, por ejemplo:

o CL-USER 8 : 1 > (untrace factorial)


(FACTORIAL)

EJEMPLOS APLICATIVOS

EJEMPLO1:

o CL-USER 6 : 2 > (defparameter *titulos*


'(Mr Mrs Don Señor Dr Sir Lord)
"Lista de títulos que pueden aparecer al inicio de un nombre")
*TITULOS*
o CL-USER 7 : 2 > (defun PrimerNombre (nombre)
(if (member (first nombre) *titulos*)
(PrimerNombre (rest nombre))
(first nombre)))
FIRST-NAME
o CL-USER 8 : 2 > (PrimerNombre '(Mr Dr Don Mario Cardenas Sanchez))
MARIO
EJEMPLO2:

Anda mungkin juga menyukai