Problem with macro with-timer
Philippe Brochard
pbrochard at common-lisp.net
Tue Mar 4 22:53:28 UTC 2014
Andrea De Michele writes:
[...]
> I think that gensym it is not created only once at compile time, but gensym as
> default value is evaluated each time before macroexpansion.
>
> If I evaluate several time this form:
>
> (with-timer (2) (focus-frame-by (find-frame-by-name "notification")))
>
> the error is each time different:
>
> CLFSWM> (with-timer (2) (focus-frame-by (find-frame-by-name "notification")))
> ; Evaluation aborted on #<UNBOUND-VARIABLE G1462 {1003A88ED3}>.
> CLFSWM> (with-timer (2) (focus-frame-by (find-frame-by-name "notification")))
> ; Evaluation aborted on #<UNBOUND-VARIABLE G1463 {1003B1B463}>.
>
> gensym is evaluated each time and its return value is each time
> different (#:G1462 and #:G1463 in this case)
>
The symbol is created at compile time (macro expansion) and is new each
time we encounter a with-timer. When you quote it, you make (gensym)
available at evaluation time.
A test:
(defmacro test (&optional (x '(gensym)) (y (gensym)) (z (gensym)))
`(list ,x ,y ',z))
(defun test1 ()
(print (macroexpand-1 '(test)))
(print (macroexpand-1 '(test)))
(print (macroexpand-1 '(test))))
=>
(LIST (GENSYM) #:G3242 '#:G3243)
(LIST (GENSYM) #:G3244 '#:G3245)
(LIST (GENSYM) #:G3246 '#:G3247)
The error comes from the fact that (gensym) create a new symbol but
#G:3242 is a symbol not a bounded variable. And the list function
try to evaluate #:G3242.
So we can write it as the x or z parts to prevent the error.
> I have found an old blog post that explains this strange macro parameter
> behaviour:
>
> http://www.findinglisp.com/blog/2005/01/keyword-parameters-in-macro-expansions.html
>
Thanks for the blog post. Those type of bugs are pretty hard to
spot. And the only place we used it is with a named id in a contrib
module.
I haven't tested sufficiently this macro :-(
> PS: thank you very much for this wonderful windows manager.
>
Thanks a lot for using it! And welcome on this list if I haven't wish
you this before. (I'm not accustomed to the new mailing list system to
know new members).
More information about the clfswm-devel
mailing list