[pro] Keyword arguments and compiler macros

Nikodemus Siivola nikodemus at random-state.net
Sat Dec 3 10:26:11 UTC 2011


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




More information about the pro mailing list