From: Francogrex on
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
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
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
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
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
 |  Next  |  Last
Pages: 1 2
Prev: allegro serv, showing an image
Next: ABCL 0.21 released