From: Barry Margolin
Subject: Re: A &key question, this time...
Date: 
Message-ID: <1lq8p3INNm2k@early-bird.think.com>
In article <·····················@elin.e.kth.se> ·······@e.kth.se (Richard Levitte) writes:
>Destructuring in lambda-lists is a pretty neat thing. I only wonder
>how it should look when defining a keyword, to make it unambigous.

I assume what you're trying to accomplish is something like

(foo-macro :keyword (a b c))

and have a destructuring list that automatically binds three variables to
the A, B, and C symbols in the parameter list.

(defmacro foo-macro (&key ((:keyword (arg1 arg2 arg3)) '(nil nil nil)))
  ...)

I believe the explicit default value is necessary because otherwise the
default would be for :KEYWORD parameter to be (), which doesn't have a
compatible shape with (ARG1 ARG2 ARG3).

You could also write

(defmacro foo-macro (&key ((:keyword (&optional arg1 arg2 arg3))))
  ...)

It could get even more complicated, to allow this:

(foo-macro :keyword (:arg2 b :arg1 a :arg3 c))

This would be defined this way:

(defmacro foo-macro (&key ((:keyword (&key arg1 arg2 arg3))))
  ...)

In this case the explicit defaults aren't necessary, because the nested
&OPTIONAL or &KEY allows the individual sub-components of the destructuring
list to default.

Note that not all implementations get this right.  Neither Lucid CL 4.1 nor
WCL 2.1 can handle any of these.  Lucid complains "(ARG1 ARG2 ARG3) is a
constant, but a variable is expected" at macro definition time, while WCL
complains "(ARG1 ARG2 ARG3) is not a SYMBOL" at macro expansion time.  I
believe this is a bug, since destructuring specifies that "Anywhere in a
\term{macro lambda list} where a parameter name can appear, ... a
\term{destructuring lambda list} can appear in place of the parameter
name."

Symbolics Genera 8.1 and CMUCL 16d process them correctly.

WCL also can't handle destructured &OPTIONAL variables:

(defmacro foo-macro (&optional ((arg1 arg2 arg3) '(nil nil nil)))
  ...)

The general problem is that its implementation of DESTRUCTURING-BIND treats
any destructuring lambda list that contains an &keyword as an ordinary
function lambda list, so it can't handle nested destructuring within such
lists.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar