[pro] Keyword arguments and compiler macros
Nikodemus Siivola
nikodemus at random-state.net
Fri Dec 2 08:28:39 UTC 2011
On 1 December 2011 23:12, Juan Jose Garcia-Ripoll
> I _now_ think that the compiler macro processor should simply recognize the
> failure to parse the form and return the original form, unprocessed
I'm not convinced.
Firstly, the (admittedly non-normative) final example in the
DEFINE-COMPILER-MACRO dictionary entry shows that this isn't exactly
traditional or something writers of portable code can expect.
The same example also, as a practical consideration to those trying to
write portable code, shows how using &REST and &ALLOW-OTHER-KEYS makes
writing such compiler macros possible.
However, the possibility of non-constant keywords is not the only
reason it is tricky. Consider this:
(defun foo (&key a b c) ...)
Let's assume that FOO can be implemented quite efficiently if you know
A comes from BAR. In addition to dealing with constant arguments,
that's one of the major use-cases for compiler-macros after all.
(define-compiler-macro foo (&whole form &key a b)
(if (can-optimize-p a b)
(optimize a b)
form))
Now let's take a look at a call-site:
(foo :b (incf i) :a (bar i))
Unless CAN-OPTIMIZE-P recognizes that B may have side-effects and
therefor returns NIL, the compiler-macro has a bug. This means that as
a practical matter compiler-macro writers dealing with keywords
virtually /always/ need to include &REST in their lambda-lists, and
use it to preserve the order of evaluation.
...which in turn means that if even if an implementation makes
compiler-macros fire only when all keywords specified are constant
ones, compiler-macro writers /still/ need to look at &REST.
Relying on the implementation to provide sufficient rebinding to
preserve the order of side-effects would lead to unportable code with
subtle bugs -- the worst kind.
Cheers,
-- Nikodemus
More information about the pro
mailing list