Prev: allegro serv, showing an image
Next: ABCL 0.21 released
From: Francogrex on 29 Jul 2010 03:10 Given that macros are a delicate matter, will this simple (and useless) example below generate any issues? What sort of standard test one would use to avoid leaks (like variable capture etc)? (defmacro myfor (X Y ACTION Z) `(if (equal ',Z 'END) (iter (for i from ,X to ,Y) (,ACTION i)) (error "~% ERROR: not a proper syntax"))) (macroexpand '(myfor 0 100 print END)) (myfor 0 15 collect end)
From: Kenneth Tilton on 29 Jul 2010 04:06 Francogrex wrote: > Given that macros are a delicate matter,... No more so than programming in general since macros /are/ programming in general. >... will this simple (and > useless) example... If it is useless it is not an example. Only "real world" edifies. >... below generate any issues? What sort of standard test > one would use to avoid leaks (like variable capture etc)? gensym? > > (defmacro myfor (X Y ACTION Z) > `(if (equal ',Z 'END) Your "syntax" is "all uses must end in end? That seems more irritating than syntactical. And why are you waiting until runtime to announce what could be announced at macro expansion time? kt -- http://www.stuckonalgebra.com "The best Algebra tutorial program I have seen... in a class by itself." Macworld
From: Captain Obvious on 29 Jul 2010 06:33 F> Given that macros are a delicate matter, will this simple (and F> useless) example below generate any issues? It depends on how you define 'issues'. F> What sort of standard test one would use to avoid leaks F> (like variable capture etc)? You can avoid variable caputure by using gensym or helper macros which use it. F> (defmacro myfor (X Y ACTION Z) F> `(if (equal ',Z 'END) F> (iter (for i from ,X to ,Y) (,ACTION i)) F> (error "~% ERROR: not a proper syntax"))) I'd rather do syntax check in macroexpansion time: (defmacro myfor (X Y ACTION Z) (if (equal Z 'END) `(iter (for i from ,X to ,Y) (,ACTION i)) (error "~% ERROR: not a proper syntax")))
From: Pascal Costanza on 29 Jul 2010 07:19 On 29/07/2010 12:33, Captain Obvious wrote: > F> Given that macros are a delicate matter, will this simple (and > F> useless) example below generate any issues? > > It depends on how you define 'issues'. > > F> What sort of standard test one would use to avoid leaks > F> (like variable capture etc)? > > You can avoid variable caputure by using gensym or helper macros which > use it. > > F> (defmacro myfor (X Y ACTION Z) > F> `(if (equal ',Z 'END) > F> (iter (for i from ,X to ,Y) (,ACTION i)) > F> (error "~% ERROR: not a proper syntax"))) > > I'd rather do syntax check in macroexpansion time: > > (defmacro myfor (X Y ACTION Z) > (if (equal Z 'END) > `(iter (for i from ,X to ,Y) (,ACTION i)) > (error "~% ERROR: not a proper syntax"))) The 'i should be protected with a gensym. (ACTION could be a macro.) Pascal -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Thomas A. Russ on 29 Jul 2010 19:38
Francogrex <franco(a)grex.org> writes: > Given that macros are a delicate matter, will this simple (and > useless) example below generate any issues? What sort of standard test > one would use to avoid leaks (like variable capture etc)? Well, I'm not sure about "tests", but some general principles are: Variable Capture: * Do not introduce named (as opposed to gensym'd) variables in any context into which the macro injects code passed in by an argument. * The same rule applies to local function definitions. Also, you do need to be concerned with what you do at run time versus macroexpansion time. For example, in what you have below, you only detect the error at run time, when it could also be done at expansion time. In particular since you quote the value of Z from macroexpansion time, it must be the symbol END to be syntactically correct. And it is much better to catch a macro syntax error like that during expansion rather than at run time. > (defmacro myfor (X Y ACTION Z) > `(if (equal ',Z 'END) > (iter (for i from ,X to ,Y) (,ACTION i)) > (error "~% ERROR: not a proper syntax"))) > > (macroexpand '(myfor 0 100 print END)) > > (myfor 0 15 collect end) Um, this isn't what I get in my lisp.... I get the following as an expansion: (IF (EQUAL 'END 'END) (ITER (FOR I FROM 0 TO 100) (PRINT I)) (ERROR "~% ERROR: not a proper syntax")) That is because the syntax check is inside the backquote, and thus part of the emitted (expanded) code not part of the expansion. To get the output you have, you need to change when things happen and write the macro as follows: (defmacro myfor (X Y ACTION Z) (if (equal Z 'END) `(iter (for i from ,X to ,Y) (,ACTION i)) (error "~% ERROR: not a proper syntax"))) Now in this macro, you are safe using "I" as a variable because you don't really put any code from the user inside the binding of I. All you allow are ITER actions that are presumably simply symbols. -- Thomas A. Russ, USC/Information Sciences Institute |