[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

I don't understand the syntax definition Destructuring Lambda Lists

Jim Newton

12/14/2015 2:06:00 PM

I'm trying to understand the corner case syntax of Destructuring Lambda Lists by reading
http://clhs.lisp.se/Body....

Is it correct as written? Or is the recursive step omitted in the specification?

It seems to me that reqvars should be defined as follows

reqvars := (var | lambda-list)*

Otherwise why is a destructuring-bind call like the following syntactically correct
(destructuring-bind ((&key a) (&optional b) c) '((:a 1) (2) 3)
(list a b c))
--> (1 2 3)


http://clhs.lisp.se/Body....
A destructuring lambda list has the following syntax:

reqvars::= var*
optvars::= [&optional {var | (var [init-form [supplied-p-parameter]])}*]
restvar::= [{&rest | &body} var]
keyvars::= [&key {var | ({var | (keyword-name var)} [init-form [supplied-p-parameter]])}*
[&allow-other-keys]]
auxvars::= [&aux {var | (var [init-form])}*]
envvar::= [&environment var]
wholevar::= [&whole var]
lambda-list::= (wholevar reqvars optvars restvar keyvars auxvars) |
(wholevar reqvars optvars . var)



29 Answers

Barry Margolin

12/14/2015 3:19:00 PM

0

In article <ef2a3e3a-6a19-47c5-b8ec-bacd8d12e78f@googlegroups.com>,
Jim Newton <jimka.issy@gmail.com> wrote:

> I'm trying to understand the corner case syntax of Destructuring Lambda
> Lists by reading
> http://clhs.lisp.se/Body....
>
> Is it correct as written? Or is the recursive step omitted in the
> specification?
>
> It seems to me that reqvars should be defined as follows
>
> reqvars := (var | lambda-list)*
>
> Otherwise why is a destructuring-bind call like the following syntactically
> correct
> (destructuring-bind ((&key a) (&optional b) c) '((:a 1) (2) 3)
> (list a b c))
> --> (1 2 3)

The recursive nature isn't described in the grammar. The text says that
destructuring lambda lists are just like macro lambda lists, except that
&environment can't be used. And the section on macro lambda lists has a
subsection:

http://clhs.lisp.se/Body/...

that says "Anywhere in a macro lambda list where a parameter name can
appear, and where ordinary lambda list syntax ... does not otherwise
allow a list, a destructuring lambda list can appear in place of the
parameter name."

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Jim Newton

12/14/2015 4:15:00 PM

0


>
> http://clhs.lisp.se/Body/...
>
> that says "Anywhere in a macro lambda list where a parameter name can
> appear, and where ordinary lambda list syntax ... does not otherwise
> allow a list, a destructuring lambda list can appear in place of the
> parameter name."
>

This is interesting. It apparently means that mean a "recursive" lambda-list is allowed in place of the &whole, &rest and &aux variables?
And also for the &key variable in the form &key ((:key HERE)) and &optional (HERE default),
as in both of these places a variable name but not a list is accepted in a ordinary lambda list.

I'm not sure if I understand what using a recursive lambda means in place of the &aux variable.

Barry Margolin

12/14/2015 4:41:00 PM

0

In article <f915c916-6b7a-4de2-aea4-b8ed7c1913db@googlegroups.com>,
Jim Newton <jimka.issy@gmail.com> wrote:

> >
> > http://clhs.lisp.se/Body/...
> >
> > that says "Anywhere in a macro lambda list where a parameter name can
> > appear, and where ordinary lambda list syntax ... does not otherwise
> > allow a list, a destructuring lambda list can appear in place of the
> > parameter name."
> >
>
> This is interesting. It apparently means that mean a "recursive" lambda-list
> is allowed in place of the &whole, &rest and &aux variables?

I suppose. It's kind of silly to use it with &whole, since the point of
&whole is to provide a way to access the original form before
destructuring.

> And also for the &key variable in the form &key ((:key HERE)) and &optional
> (HERE default),
> as in both of these places a variable name but not a list is accepted in a
> ordinary lambda list.
>
> I'm not sure if I understand what using a recursive lambda means in place of
> the &aux variable.

&aux ((a &rest b) *list*)

should be equivalent to

&aux (a (car *list*)) (b (cdr *list*))

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Kaz Kylheku

12/14/2015 5:22:00 PM

0

On 2015-12-14, Jim Newton <jimka.issy@gmail.com> wrote:
>
>>
>> http://clhs.lisp.se/Body/...
>>
>> that says "Anywhere in a macro lambda list where a parameter name can
>> appear, and where ordinary lambda list syntax ... does not otherwise
>> allow a list, a destructuring lambda list can appear in place of the
>> parameter name."
>>
>
> This is interesting. It apparently means that mean a "recursive"
> lambda-list is allowed in place of the &whole, &rest and &aux
> variables?

Yes; any variable: e.g.

(destructuring-bind (a b &whole (c d)) '(1 2) (list a b c d))

--> (1 2 1 2)

> I'm not sure if I understand what using a recursive lambda means in
> place of the &aux variable.

It's an eggcorn case.

Data point, CLISP:

(destructuring-bind (a b &aux (c d)) '(1 2) (list a b))
*** - LET*: variable D has no value

Kaz Kylheku

12/14/2015 5:25:00 PM

0

On 2015-12-14, Kaz Kylheku <kaz@kylheku.com> wrote:
> On 2015-12-14, Jim Newton <jimka.issy@gmail.com> wrote:
>>
>>>
>>> http://clhs.lisp.se/Body/...
>>>
>>> that says "Anywhere in a macro lambda list where a parameter name can
>>> appear, and where ordinary lambda list syntax ... does not otherwise
>>> allow a list, a destructuring lambda list can appear in place of the
>>> parameter name."
>>>
>>
>> This is interesting. It apparently means that mean a "recursive"
>> lambda-list is allowed in place of the &whole, &rest and &aux
>> variables?
>
> Yes; any variable: e.g.
>
> (destructuring-bind (a b &whole (c d)) '(1 2) (list a b c d))
>
> --> (1 2 1 2)

Having said "any", it doesn't make sense for the &environment variable.

That is to say &environment (a b) doesn't make sense (at least not in
the light of portability) because the environment is almost certainly
an atom.

Barry Margolin

12/14/2015 6:58:00 PM

0

In article <20151214092304.348@kylheku.com>,
Kaz Kylheku <kaz@kylheku.com> wrote:

> On 2015-12-14, Kaz Kylheku <kaz@kylheku.com> wrote:
> > On 2015-12-14, Jim Newton <jimka.issy@gmail.com> wrote:
> >>
> >>>
> >>> http://clhs.lisp.se/Body/...
> >>>
> >>> that says "Anywhere in a macro lambda list where a parameter name can
> >>> appear, and where ordinary lambda list syntax ... does not otherwise
> >>> allow a list, a destructuring lambda list can appear in place of the
> >>> parameter name."
> >>>
> >>
> >> This is interesting. It apparently means that mean a "recursive"
> >> lambda-list is allowed in place of the &whole, &rest and &aux
> >> variables?
> >
> > Yes; any variable: e.g.
> >
> > (destructuring-bind (a b &whole (c d)) '(1 2) (list a b c d))
> >
> > --> (1 2 1 2)
>
> Having said "any", it doesn't make sense for the &environment variable.
>
> That is to say &environment (a b) doesn't make sense (at least not in
> the light of portability) because the environment is almost certainly
> an atom.

Right -- it only makes sense when the value of the single variable would
be a list. Since the type of the environment isn't specified, there's no
way to know what kind of list to put there.

So there's nothing syntactically prohibiting the use of a destructuring
list there, but semantically it wouldn't work.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Jim Newton

12/15/2015 9:39:00 AM

0


>
> (destructuring-bind (a b &whole (c d)) '(1 2) (list a b c d))
>
> --> (1 2 1 2)
>

From my understanding of the spec, the &whole must precede all required arguments.
Am I wrong? In no case, that I see in the spec, does whoever follow reqvars

reqvars::= var*
optvars::= [&optional {var | (var [init-form [supplied-p-parameter]])}*]
restvar::= [{&rest | &body} var]
keyvars::= [&key {var | ({var | (keyword-name var)} [init-form [supplied-p-parameter]])}*
[&allow-other-keys]]
auxvars::= [&aux {var | (var [init-form])}*]
wholevar::= [&whole var]
lambda-list::= (wholevar envvar reqvars envvar optvars envvar
restvar envvar keyvars envvar auxvars envvar) |
(wholevar envvar reqvars envvar optvars envvar . var)
pattern::= (wholevar reqvars optvars restvar keyvars auxvars) |
(wholevar reqvars optvars . var)

Kaz Kylheku

12/15/2015 3:32:00 PM

0

On 2015-12-15, Jim Newton <jimka.issy@gmail.com> wrote:
>
>>
>> (destructuring-bind (a b &whole (c d)) '(1 2) (list a b c d))
>>
>> --> (1 2 1 2)
>>
>
> From my understanding of the spec, the &whole must precede all
> required arguments.
> Am I wrong? In no case, that I see in the spec, does whoever follow
> reqvars

You are right. I banged out the above in CLISP which accepts &whole
anywhere.

It's easier to recognize &whole anywhere, like &environment, than to add
gratuitous logic to generate a diagnostic when it's not at the front.

"You used &whole, but a boolean flag added just for this purpose tells
me we're not at the front of the lambda list any more. Bad programmer!"

Jim Newton

12/15/2015 5:30:00 PM

0


>
> You are right. I banged out the above in CLISP which accepts &whole
> anywhere.
>
> It's easier to recognize &whole anywhere, like &environment, than to add
> gratuitous logic to generate a diagnostic when it's not at the front.
>
> "You used &whole, but a boolean flag added just for this purpose tells
> me we're not at the front of the lambda list any more. Bad programmer!"

Perhaps that's one way to look at it. Another way to look at it is that the spec says &whole
has special meaning only if it appears before all required arguments, otherwise it is simply
a normal variable. According to my reading of the spec (lambda (a &whole) ...) is a binary function.
Am I reading something wrong?

Barry Margolin

12/15/2015 5:40:00 PM

0

In article <7b7f5dde-1a67-4ec0-bd5e-5a6c9dad5872@googlegroups.com>,
Jim Newton <jimka.issy@gmail.com> wrote:

> >
> > You are right. I banged out the above in CLISP which accepts &whole
> > anywhere.
> >
> > It's easier to recognize &whole anywhere, like &environment, than to add
> > gratuitous logic to generate a diagnostic when it's not at the front.
> >
> > "You used &whole, but a boolean flag added just for this purpose tells
> > me we're not at the front of the lambda list any more. Bad programmer!"
>
> Perhaps that's one way to look at it. Another way to look at it is that the
> spec says &whole
> has special meaning only if it appears before all required arguments,
> otherwise it is simply
> a normal variable. According to my reading of the spec (lambda (a &whole)
> ...) is a binary function.
> Am I reading something wrong?

Since &whole only has a special meaning in macro lambda lists, not
ordinary functions, that is indeed a binary function.

I wouldn't mind an implementation displaying a warning about random
function/macro arguments beginning with &, though.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***