On 2 December 2011 21:42, Juan Jose Garcia-Ripoll
A different issue is the utility of &key. I do not buy the argument that &key should always be used with &allow... in compiler macros. This forfeits any use of &key at all because the values are _never_ going to be trusted at all: one of the arguments might be a variable name and the parser will confuse the user about expectations.
Well, they /can/ be used to provide defaults. (Not that that's so useful since you /still/ need to walk &REST, but...)
If on the other hand this definition
(define-compiler-macro foo (&rest my-args &key some-key-arg) ...)
implies that the compiler macro will refuse parsing (without an error) when some argument is not an allowed keyword, then this actually has some utility.
Point taken.
Also, I just found a hilarious --apparently universal-- bug in this area:
(defun foo (&key ((a ax) t)) (format nil "a=~S" ax))
(define-compiler-macro foo (&key ((a ax) t)) (format nil "a=~S" ax))
(compile nil `(lambda () (foo 'a 42))) =| ERROR, unknown keyword 'A
(funcall (compile nil `(lambda () (foo a 42)))) => "a=42"
SBCL, CCL, Clisp, and Lispworks all share this beauty.
Now, fixing this (at least in SBCL) is simple enough, but raises the question of what to do about non-constant form where a keyword argument is expected. Complaining about "unknown keyword argument FOO" when FOO is actually a variable that may evaluate to a perfectly valid keyword at runtime seems a bit suspect.
So, on reflection, I've made a 180 degree turnabout and now think that declining to expand compiler-macros with unknown or variable keyword arguments is The Right Thing to do unless &ALLOW-OTHER-KEYS is explicitly specified.
Cheers,
-- nikodemus