Sunteți pe pagina 1din 23

Tema 5: Macros

Sesin 14: Macros

mircoles 23 de marzo de 2011

Hoy veremos...
Conceptos generales
Quasiquotation
Macros en Scheme
Ejemplos de macros

mircoles 23 de marzo de 2011

Referencias
Captulo 3.7 Programming Language Pragmatics: Macro Expansion

mircoles 23 de marzo de 2011

Definicin de macro
Una macro consiste en una plantilla o meta-expresin que define un patrn
de sustitucin formado por unas variables libres y unas expresiones
textuales.
Es una tcnica de generacin de cdigo
Se realiza en la fase de preprocesamiento (en lenguajes compilados como C
o C++)
Previamente a la evaluacin de la expresin (en lenguajes interpretados)
Las macros son un meta-lenguaje, en el sentido de que permiten controlar y
definir expresiones del propio lenguaje
No estn sometidas a la sintaxis del lenguaje
mircoles 23 de marzo de 2011

Evolucin histrica de las macros


Orgen de las macros: ensamblador
Se incorporan en lenguajes ms prximos al ensamblador como C y en
lenguajes avanzados como LISP o Scheme como una posibilidad de
extender el lenguaje
En la actualidad no se usan demasiado, aunque su caracterstica de metaprogramacin ha dejado una huella muy importante en los lenguajes de
programacin:
Anotaciones en Java
Scaffolding en Ruby & Rails
Herramientas de MDA de generacin automtica de cdigo
mircoles 23 de marzo de 2011

Macros en C
Ejemplos de Macros:
#define LINE_LEN 80
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define SWAP(a,b) {int t = (a); (a) = (b); (b) = t;}

Una llamada a la macro:


x = MAX(p+q, r+s);

Se sustituir (expansin de la macro) por:


x = ((p+q) > (r+s) ? (p+q) : (r+s))

mircoles 23 de marzo de 2011

Las macros permiten definir nuevos lenguajes


Ejemplo en C:

#define then
#define begin {
#define end ;}

Lo probamos:

if (i > 0) then
begin
a = 1;
b = 2
end

Esta posibilidad es mucho ms potente en las macros de Scheme


Lenguajes de dominio: las universidades y departamentos de investigacin
inventan lenguajes adaptados especificamente a dominios especficos como
robtica. Es muy fcil disear prototipos de estos lenguajes con las macros
de Scheme
mircoles 23 de marzo de 2011

Problemas de la expansin en C
El preprocesador de C extiende la macro de forma ciega sin tener ninguna
relacin con el proceso de compilacin posterior
Esto puede producir errores. Por ejemplo, si llamamos a MAX(x++, y++) la
expansin de la macro produce el siguiente resultado:
((a++) > (b++) ? (a++) : (b++))

LISP y Scheme utilizan las llamadas macros higinicas que encapsulan


implcitamente sus argumentos y evitan los errores de las macros de C

mircoles 23 de marzo de 2011

Quasiquotation
La forma especial quasiquote junto con unquote permite evaluar de forma
arbitraria las expresiones que nos interesan en una lista:
(define bar 2)
(quasiquote (foo (unquote bar) baz))

Se utiliza el smbolo backquote y la coma:


`(foo ,bar baz) --> (foo 2 baz)

mircoles 23 de marzo de 2011

--> (foo 2 baz)


(define a 2)
(define b 'hola)
'(1 a b)
(quasiquote (1 ,a ,b))
`(1 ,a ,b)
`(1 ,a ,b ,c)
`(1 ,+ ,-)

Macros en Scheme
Se basan en las formas especiales define-syntax y syntax-rules
Sintaxis de una macro:
(define-syntax <keyword>
(syntax-rules (<literales>)
((<patron-1> <plantilla-1>)
...
(<patron-n> <plantilla-n>))))

Ejemplo: mi-or
(define-syntax mi-or
(syntax-rules ()
((mi-or) #t)
((mi-or e) e)
((mi-or e1 e2 e3 ...)
(if e1 #t (mi-or e2 e3 ...)))))
mircoles 23 de marzo de 2011

Reglas de evaluacin de una macro


Para evaluar una llamada a una macro (op exp_1 ... exp_n) debemos
seguir las siguientes reglas:
Buscar la definicin de la macro. Buscar la forma especial definesyntax en la que aparece op como clave.
Emparejar. Buscar en la definicin de la macro la regla sintctica con la
que es posible emparejar la expresin (op exp_1 ... exp_n) que
estamos evaluando. Si hay ms de una regla con la que se puede
emparejar la expresin, escogemos la primera de ellas.
Transformar. Aplicar la regla para transformar la expresin.
Evaluar. Evaluar la expresin resultante. En el caso en que la expresin
resultante contenga una llamada a una macro se evaluar siguiendo estas
mismas reglas.
mircoles 23 de marzo de 2011

Expansin de una macro


Expansin de la llamada a la macro:
(mi-or (equal? x 2) #f #t (equal? y 3))

mircoles 23 de marzo de 2011

Sintaxis alternativas vlidas


(define-syntax mi-or
(syntax-rules ()
((_) #t)
((_ e) e)
((_ e1 e2 e3 ...)
(if e1 #t (mi-or e2 e3 ...)))))

(define-syntax mi-or
(syntax-rules ()
((op) #t)
((op e) e)
((op e1 e2 e3 ...)
(if e1 #t (mi-or e2 e3 ...)))))

mircoles 23 de marzo de 2011

Depuracin de macros

(define-syntax mi-or
(syntax-rules ()
((op) #t)
((op e) e)
((op e1 e2 e3 ...)
(if e1 #t (mi-or e2 e3 ...)))))

mircoles 23 de marzo de 2011

Macro make-procedure
(define-syntax make-procedure
(syntax-rules ()
((make-procedure (x ...) expr ...)
(lambda (x ...) expr ...))))

mircoles 23 de marzo de 2011

Macro mi-let

mircoles 23 de marzo de 2011

Macro mi-let
(define-syntax mi-let
(syntax-rules ()
((mi-let ((x v) ...) e ...)
((lambda (x ...) e ...) v ...))))

mircoles 23 de marzo de 2011

Macro mi-cond

mircoles 23 de marzo de 2011

Macro mi-cond
(define-syntax mi-cond
(syntax-rules (=> else)
((mi-cond (else => expr))
expr)
((mi-cond (test1 => expr1))
(if test1 expr1))
((mi-cond (test1 => expr1) (test2 => expr2) ...)
(if test1 expr1 (mi-cond (test2 => expr2) ...)))))

mircoles 23 de marzo de 2011

Macro multi-print (paradigma procedural)

mircoles 23 de marzo de 2011

Macro multi-print (paradigma procedural)


(define-syntax multi-print
(syntax-rules ()
((multi-print arg1 arg2 ...)
(begin (print arg1)
(newline)
(multi-print arg2 ...)))
((multi-print) #t)))

mircoles 23 de marzo de 2011

Macro when (paradigma procedural)

mircoles 23 de marzo de 2011

Macro when (paradigma procedural)


(define-syntax when
(syntax-rules ()
((when condition expr1 expr2 ...)
(if condition (begin expr1 expr2 ...) #f))))

mircoles 23 de marzo de 2011

S-ar putea să vă placă și