Lisp

Published on February 2017 | Categories: Documents | Downloads: 47 | Comments: 0 | Views: 379
of 23
Download PDF   Embed   Report

Comments

Content

´
Introduccion

Backquote

Definiendo macros

Probando macros

´ II
Metodolog´ıas de Programacion
Macros en Lisp
´
Dr. Alejandro Guerra-Hernandez
Departamento de Inteligencia Artificial
Facultad de F´ısica e Inteligencia Artificial
[email protected]
http://www.uv.mx/aguerra

Maestr´ıa en Inteligencia Artificial 2012

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

Programas que escriben programas

I

I

´ de una macro es esencialmente el de una
La definicion
´ que genera codigo
´
funcion
Lisp –un programa que genera
programas.
´ produce un resultado,
Diferencia importante: Una funcion
´ que al ser
pero una macro produce una expresion
evaluada produce un resultado.

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplo: nil!

I

Supongan que queremos escribir la macro nil! que
asigna a su argumento el valor nil. Queremos que
(nil! x) tenga el mismo efecto que (setq x nil)
CL-USER> (defmacro nil! (var)
(list ’setq var nil))
NIL!
CL-USER> (nil! x)
NIL
CL-USER> x
NIL

1
2
3
4
5
6
7

I

´
¿Como
evalua
´ Lisp la llamada en la l´ınea 4?

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

´ de una macro
Evaluacion

I

Lisp identifica a nil! como una macro y:
I

I

´ especificada por la definicion
´ de la
Construye la expresion
´ lo que
marco en la fase conocida como macro-expansion,
´ (setq x nil); y entonces
genera la expresion
´ obtenida en lugar de la llamada original
Evalua la expresion
a la macro, esto es, se evalua
´ (setq x nil), como si el
programador la hubiese tecleado.

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

´ solo
´ en algunas partes
Deteniendo la evaluacion

I

1
2
3
4
5
6
7
8

´ especial de nuestro conocido
El backquote es una version
quote, que puede ser usado para definir moldes de
expresiones Lisp.
CL-USER 3
(A B C)
CL-USER 4
(A B C)
CL-USER 5
3
CL-USER 6
(A (2 C))

> (list ’a ’b ’c)
> ‘(a b c)
> (setf a 1 b 2 c 3)
> ‘(a (,b c))

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

Ventajas de backquote

I

1
2
3
4

´ faciles
´
Hace que las expresiones sean mas
de leer, debido
´ con apostrofo
´
a que la expresion
invertido es similar a su
´ Vean las definiciones de nil!
macro-expansion.
(defmacro nil!
(list ’setq
(defmacro nil!
‘(setq ,var

(var)
var nil))
(var)
nil))

´
Introduccion

Backquote

Definiendo macros

Probando macros

´ complejo: nif
Un ejemplo mas

I
1
2
3
4

´
un if numerico:
CL-USER 8 > (mapcar #’(lambda(x)
(nif x ’p ’c ’n))
’(0 2.5 -8))
(C P N)

Ejemplos

´
Introduccion

Backquote

Definiendo macros

´
Nif con apostrofo

1
2
3
4
5

(defmacro nif (expr pos zero neg)
‘(case (truncate (signum ,expr))
(1 ,pos)
(0 ,zero)
(-1 ,neg)))

Probando macros

Ejemplos

´
Introduccion

Backquote

Definiendo macros

´
Nif sin apostrofo

1
2
3
4
5
6

(defmacro nif (expr pos zero neg)
(list ’case
(list ’truncate (list ’signum expr))
(list 1 pos)
(list 0 zero)
(list -1 neg)))

Probando macros

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Coma-arroba

I

1
2
3
4
5
6

´ que en lugar de
Funciona como la coma normal, solo
´ que antecede, inserta su
insertar el valor de la expresion
´
´ externos:
valor removiendo los parentesis
mas
CL-USER 10 > (setq b ’(1 2 3))
(1 2 3)
CL-USER 11 > ‘(a ,b c)
(A (1 2 3) C)
CL-USER 12 > ‘(a ,@b c)
(A 1 2 3 C)

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplo de uso: mi-when

1
2
3

(defmacro mi-when (test &body body)
’(if ,test
(progn ,@body)))

´
el parametro
&body toma un numero
arbitrario de argumentos
´
´ progn.
y el operador coma-arroba los inserta en un solo

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

Definiendo macros simples

I

1
2

Se comienza con la llamada a la macro que queremos
´
definir. Escribirla en un papel y abajo escriban la expresion
que quieren producir con la macro:
llamada: (mem-eq obj lst)
expansi´
on: (member obj lst :test #’eq)

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

´
Parametros
de la macro

I

1

´
La llamada nos sirve para definir los parametros
de la
macro. En este caso, como necesitamos dos argumentos,
´
el inicio de la macro sera:
(defmacro mem-eq (obj lst)

´
Introduccion

Backquote

Definiendo macros

Probando macros

Cuerpo de la macro
I

I

I

Para cada argumento en la llamada a la macro, tracen un
´
l´ınea hac´ıa donde son insertadas en la expansion.
´
Comiencen el cuerpo de la macro con un apostrofo
invertido.
´ expresion
´ por expresion:
´
Ahora lean la expansion
´ en la llamada,
1. Si no hay una l´ınea conectado la expresion
´ tal cual en el cuerpo de la
entonces escribir la expresion
macro.
´ escriban la expresion
´ precedida por
2. Si hay una conexion,
una coma.

1
2

(defmacro mem-eq (obj lst)
‘(member ,obj ,lst :test #’eq))

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Macros de aridad indeterminada
I

(defmacro while (test &body body)
‘(do ()
((not ,test))
,@body))

1
2
3
4

I
1
2
3
4
5
6

Hay que recurrir a coma-arroba:

y obtenemos una nueva estructura de control
CL-USER> (let ((i 0))
(while (< i 10)
(princ i)
(setf i (1+ i))))
0123456789
NIL

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

Macro expansiones

I

I

´ complejas, es necesario poder observar
Para macros mas
´ ha sido correcta.
si la expansion
Para ello lisp provee dos funciones predefinidas:
I

I

macroexpand muestra como la macro se expandir´ıa antes
de ser evaluada. Si la macro hace uso de otras macros,
´ de la expansion
´ es de poca utilidad.
esta revision
´ macroexpand-1 muestra la expansion
´ de un
La funcion
´ paso.
solo

´
Introduccion

Backquote

Definiendo macros

Probando macros

´
Ejemplos de macro expansion

1
2
3
4
5
6
7
8
9
10

CL-USER 2 > (pprint(macroexpand
’(while (puedas) (rie))))
(BLOCK NIL
(LET ()
(DECLARE (IGNORABLE))
(DECLARE)
(TAGBODY
#:G747 (WHEN (NOT (PUEDAS)) (RETURN-FROM NIL NIL))
(RIE)
(GO #:G747))))

11
12
13
14

CL-USER 3 > (pprint (macroexpand-1
’(while (puedas) (rie))))
(DO () ((NOT (PUEDAS))) (RIE))

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Una meta macro

I

1
2

Si vamos a hacer esto muchas veces, nos convine definir
una macro:
(defmacro mac (expr)
‘(pprint (macroexpand-1 ’,expr)))

de forma que podemos evaluar ahora:
1
2
3

CL-USER> (mac (while (puedas) rie))
(DO () ((NOT (PUEDAS))) RIE)
; Not value

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Ejemplos

´
Evaluando la expansion

I

1
2
3
4

´ obtenida puede evaluarse en el TOP-LEVEL
La expansion
para experimentar con la macro:
CL-USER> (setq aux (macroexpand-1 ’(mem-eq ’a ’(a b c))))
(MEMBER ’A ’(A B C) :TEST #’EQ)
CL-USER> (eval aux)
(A B C)

´
Introduccion

Backquote

Definiendo macros

Probando macros

for, in y random-choice
1
2
3
4
5
6

(defmacro for (var start stop &body body)
(let ((gstop (gensym)))
‘(do ((,var ,start (1+ ,var))
(,gstop ,stop))
((> ,var ,gstop))
,@body)))

7
8
9
10
11
12

(defmacro in (obj &rest choices)
(let ((insym (gensym)))
‘(let ((,insym ,obj))
(or ,@(mapcar #’(lambda(c) ‘(eql ,insym ,c))
choices)))))

13
14
15
16
17
18
19

(defmacro random-choice (&rest exprs)
‘(case (random ,(length exprs))
,@(let ((key -1))
(mapcar #’(lambda(expr)
‘(,(incf key) ,expr))
exprs))))

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Corridas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

CL-USER 3 > (for x 1 8 (princ x))
12345678
NIL
CL-USER 4 > (in 3 1 2 3)
T
CL-USER 5 > (random-choice 1 2 3)
1
CL-USER 6 > (random-choice 1 2 3)
3
CL-USER 7 > (random-choice 1 2 3)
3
CL-USER 8 > (random-choice 1 2 3)
1
CL-USER 9 > (random-choice 1 2 3)
1
CL-USER 10 > (random-choice 1 2 3)
2

Probando macros

Ejemplos

´
Introduccion

Backquote

Definiendo macros

macro expansiones

1
2
3
4
5
6
7
8
9
10
11
12
13

CL-USER> (mac (for x 1 9 (princ x)))
(DO ((X 1 (1+ X))
(#:G1009 9))
((> X #:G1009)) (PRINC X))
; No value
CL-USER> (mac (in 3 1 2 3))
(LET ((#:G1010 3)) (OR (EQL #:G1010 1)
(EQL #:G1010 2)
(EQL #:G1010 3)))
; No value
CL-USER> (mac (random-choice 1 2 3))
(CASE (RANDOM 3) (0 1) (1 2) (2 3))
; No value

Probando macros

Ejemplos

´
Introduccion

Backquote

Definiendo macros

Probando macros

Bibliograf´ıa

P. Graham.
On Lisp: Advanced Techniques for Common Lisp.
Prentice Hall International, 1993.

Ejemplos

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close