So I'm implementing parse-macro from CLtL2 to fill out Allegro's
portable environment implementation a little bit, and I am scratching my
head at the specification of macro lambda lists and destructuring lambda
lists.
from the hyperspec:
-------------------
3.4.4: on macro lambda lists
&whole is followed by a single variable that is bound to the entire
macro-call form; this is the value that the macro function receives as
its first argument. If &whole and a following variable appear, they must
appear first in lambda-list, before any other parameter or lambda list
keyword. &whole *can appear at any level of a macro lambda list*. At inner
levels, the &whole variable is bound to the corresponding part of the
argument, as with &rest, but unlike &rest, other arguments are also
allowed. The use of &whole does not affect the pattern of arguments
specified.
3.4.5 on destucturing lambda lists
Destructuring lambda lists are closely related to macro lambda lists; see
Section 3.4.4 (Macro Lambda Lists). A destructuring lambda list can
contain all of the lambda list keywords listed for macro lambda lists
except for &environment, and supports destructuring in the same way. Inner
lambda lists nested within a macro lambda list have the syntax of
destructuring lambda lists.
lambda-list::= (wholevar reqvars optvars restvar keyvars auxvars) |
(wholevar reqvars optvars . var)
--------------------
Since &environment can ony appear in top level lambda list of a macro, it
would make sense that after extracting the environment argument from the
macro lambda list (if it exists) it should be possible to parse the
remaining lambda list using destructuring-bind.
However there are two problems:
1. &whole seems like it should have different semantics in a top
level macro lambda list than it would in an inner lambda list, or even
destructuring lambda list. In a macro the lambda list is a pattern to
parse the cdr of the form, and &whole allows you to bind the entire form
to a variable. What is the "entire form" in an inner lambda lists, or the
top level lambda list in a destructuring-bind?
2. problem one is complete speculation since I can't get an
implementation to handle macros defined with &whole args in inner lambda
lists, or destructuring-bind with &whole arguments anywhere. I usually
get errors like:
(destructuring-bind (&whole foo) '(1 2 3) foo)
*** - The object to be destructured should be a list with 0 elements,
not (1 2 3)
Am I misinterpreting the spec?
Matt
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.
Matthew D Swank wrote:
> So I'm implementing parse-macro from CLtL2 to fill out Allegro's
> portable environment implementation a little bit, and I am scratching my
> head at the specification of macro lambda lists and destructuring lambda
> lists.
>
> from the hyperspec:
> -------------------
> 3.4.4: on macro lambda lists
>
> &whole is followed by a single variable that is bound to the entire
> macro-call form; this is the value that the macro function receives as
> its first argument. If &whole and a following variable appear, they must
> appear first in lambda-list, before any other parameter or lambda list
> keyword. &whole *can appear at any level of a macro lambda list*. At inner
> levels, the &whole variable is bound to the corresponding part of the
> argument, as with &rest, but unlike &rest, other arguments are also
> allowed. The use of &whole does not affect the pattern of arguments
> specified.
>
> 3.4.5 on destucturing lambda lists
>
> Destructuring lambda lists are closely related to macro lambda lists; see
> Section 3.4.4 (Macro Lambda Lists). A destructuring lambda list can
> contain all of the lambda list keywords listed for macro lambda lists
> except for &environment, and supports destructuring in the same way. Inner
> lambda lists nested within a macro lambda list have the syntax of
> destructuring lambda lists.
>
> lambda-list::= (wholevar reqvars optvars restvar keyvars auxvars) |
> (wholevar reqvars optvars . var)
> --------------------
>
> Since &environment can ony appear in top level lambda list of a macro, it
> would make sense that after extracting the environment argument from the
> macro lambda list (if it exists) it should be possible to parse the
> remaining lambda list using destructuring-bind.
>
> However there are two problems:
> 1. &whole seems like it should have different semantics in a top
> level macro lambda list than it would in an inner lambda list, or even
> destructuring lambda list. In a macro the lambda list is a pattern to
> parse the cdr of the form, and &whole allows you to bind the entire form
> to a variable. What is the "entire form" in an inner lambda lists, or the
> top level lambda list in a destructuring-bind?
>
> 2. problem one is complete speculation since I can't get an
> implementation to handle macros defined with &whole args in inner lambda
> lists, or destructuring-bind with &whole arguments anywhere. I usually
> get errors like:
> (destructuring-bind (&whole foo) '(1 2 3) foo)
>
> *** - The object to be destructured should be a list with 0 elements,
> not (1 2 3)
>
> Am I misinterpreting the spec?
&whole doesn't specify how many arguments are allowed to be passed, it
just grabs the whole form, that's all.
Try (destructuring-bind (&whole foo a b c) '(1 2 3) foo)
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
On Sat, 18 Feb 2006 12:52:28 +0100, Pascal Costanza wrote:
> &whole doesn't specify how many arguments are allowed to be passed, it
> just grabs the whole form, that's all.
>
> Try (destructuring-bind (&whole foo a b c) '(1 2 3) foo)
>
>
> Pascal
Ok that makes more sense. So I could, in theory treat macro lambda lists
uniformly by a adding hidden (from the caller) &whole argument to macro
lambda lists that don't have them, and binding the env separately in a
let:
(parse-macro 'foo
'(&whole form &environment a &rest args)
'(`(+ ,@(cdr form))))
==>
(LAMBDA (#:G1075 #:G1076)
(DECLARE (IGNORABLE #:G1075 #:G1076))
(LET ((A #:G1076))
(DESTRUCTURING-BIND
(&WHOLE FORM &REST ARGS)
#:G1075
(BLOCK FOO `(+ ,@(CDR FORM))))))
(parse-macro 'foo
'(&environment a &rest args)
'(`(+ ,@args)))
==>
(LAMBDA (#:G1078 #:G1079)
(DECLARE (IGNORABLE #:G1078 #:G1079))
(LET ((A #:G1079))
(DESTRUCTURING-BIND
(&WHOLE #:G1077 &REST ARGS)
#:G1078
(BLOCK FOO `(+ ,@ARGS)))))
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.
On Sat, 18 Feb 2006 06:26:49 -0600, Matthew D Swank wrote:
>So I could, in theory treat macro lambda lists
> uniformly by a adding hidden (from the caller) &whole argument to macro
> lambda lists that don't have them, and binding the env separately in a
> let:
>
On second thought this is a horrible idea as the rest of the macro lambda
list needs to match the cdr of the form, not the whole form.
Matt
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.