Lisp HUG Maillist Archive

(HW-HUG) Lambda List Parameter &Optional Question...

Greetings to the List -

--------------------------------------------------------------------------------------------------------------------------
CL-USER 39 > (defun fred(x &optional y &key z)
                           (list x y z))
FRED

CL-USER 40 > (fred 0)

(0 NIL NIL)


CL-USER 41 > (fred 0 1)

(0 1 NIL)


CL-USER 42 > (fred 0 1 :z 2)

(0 1 2)


CL-USER 43 > (fred 0 :z 2)

Error: FRED is called with unpaired keyword in (2).
   1 (abort) Return to level 0.
   2 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other options
------------------------------------------------------------------------------------------------------------------------------

Question: The first three make perfect sense - but why not the last 
(fred 0 :z 2)

"Common Lisp The Language" (2nd edition on page 76) says, "Specifiers 
for optional parameters. If the lambda-list keyword &optional is 
present, the optional parameter specifiers are those following the 
lambda-list keyword &optional up to the next lambda-list keyword or 
the end of the list."  Also on page 76, the specification says that 
the &optional keyword must come before the &key keyword - in fact, if 
I reverse the order an error happens immediately.

In (fred 0 :z 2), why is x not bound to 0; y not bound to nil; and z 
not bound to 2????

It is acting as if the &optional y is ignoring the &key lambda 
keyword and eating the keyword variable z in the lambda list.

I feel a bit silly asking this very basic question, but I must say 
that I have never tried to mix &optional and &key parameters before 
in a lambda list.

What am I missing here?

Regards to the List from a very snowy Colorado.


Jack Harper
Secure Outcomes Inc
Evergreen, Colorado USA


Re: (HW-HUG) Lambda List Parameter &Optional Question...

Hello Jack,

Admittedly confusing at first...  But you are playing with fire  
whenever you have both &optional and &key arguments. The &optional  
sucks up the second argument, which in the last example is the  
keyword :Z, leaving a third argument that should have been paired with  
a keyword.

Optional args are nice, and so are keyword args. But you should try to  
avoid their combined use like the plague. Or else be hypervigilant  
about them when they are both present. Very few CL functions take both  
-- I can't recall any, but I'm sure there is at least one. But very few.

- DM

On Oct 30, 2009, at 13:40 PM, Jack Harper wrote:

>
> Greetings to the List -
>
> --------------------------------------------------------------------------------------------------------------------------
> CL-USER 39 > (defun fred(x &optional y &key z)
>                          (list x y z))
> FRED
>
> CL-USER 40 > (fred 0)
>
> (0 NIL NIL)
>
>
> CL-USER 41 > (fred 0 1)
>
> (0 1 NIL)
>
>
> CL-USER 42 > (fred 0 1 :z 2)
>
> (0 1 2)
>
>
> CL-USER 43 > (fred 0 :z 2)
>
> Error: FRED is called with unpaired keyword in (2).
>  1 (abort) Return to level 0.
>  2 Return to top loop level 0.
>
> Type :b for backtrace, :c <option number> to proceed,  or :? for  
> other options
> ------------------------------------------------------------------------------------------------------------------------------
>
> Question: The first three make perfect sense - but why not the last  
> (fred 0 :z 2)
>
> "Common Lisp The Language" (2nd edition on page 76) says,  
> "Specifiers for optional parameters. If the lambda-list keyword  
> &optional is present, the optional parameter specifiers are those  
> following the lambda-list keyword &optional up to the next lambda- 
> list keyword or the end of the list."  Also on page 76, the  
> specification says that the &optional keyword must come before the  
> &key keyword - in fact, if I reverse the order an error happens  
> immediately.
>
> In (fred 0 :z 2), why is x not bound to 0; y not bound to nil; and z  
> not bound to 2????
>
> It is acting as if the &optional y is ignoring the &key lambda  
> keyword and eating the keyword variable z in the lambda list.
>
> I feel a bit silly asking this very basic question, but I must say  
> that I have never tried to mix &optional and &key parameters before  
> in a lambda list.
>
> What am I missing here?
>
> Regards to the List from a very snowy Colorado.
>
>
> Jack Harper
> Secure Outcomes Inc
> Evergreen, Colorado USA
>
>

Dr. David McClain
dbm@refined-audiometrics.com




Re: (HW-HUG) Lambda List Parameter &Optional Question...

Practical Common Lisp has a good discussion of this:

http://gigamonkeys.com/book/functions.html

Mitc
>


Re: (HW-HUG) Lambda List Parameter &Optional Question...

At 02:49 PM 10/30/2009, I (Jack Harper) wrote:
>Hi,
>
>>
>>In (fred 0 :z 2), why is x not bound to 0; y not bound to nil; and z
>>not bound to 2????
>>
>>It is acting as if the &optional y is ignoring the &key lambda
>>keyword and eating the keyword variable z in the lambda list.
>>
>>I feel a bit silly asking this very basic question, but I must say
>>that I have never tried to mix &optional and &key parameters before
>>in a lambda list.
>

....and

David McClain said:


>Admittedly confusing at first...  But you are playing with fire
>whenever you have both &optional and &key arguments. The &optional
>sucks up the second argument, which in the last example is the
>keyword :Z, leaving a third argument that should have been paired with
>a keyword.
>
>Optional args are nice, and so are keyword args. But you should try to
>avoid their combined use like the plague. Or else be hypervigilant
>about them when they are both present. Very few CL functions take both
>-- I can't recall any, but I'm sure there is at least one. But very few.



Al Clark said:


>For what it's worth, Allegro CL gives exactly the same results.  This is CL
>behavior not LW.




Mitch Berkson said:

>Practical Common Lisp has a good discussion of this:
>
>http://gigamonkeys.com/book/functions.html



Howard Ding said:

>This is what is happening. If you have both optional and keyword
>arguments then you have to specify all of the optional arguments
>before you can start passing keyword arguments. This actually makes
>sense: suppose you had two optional arguments and then some keyword
>arguments. How would one distinguish if a call like (foo :a 1) was
>supposed to have :a and 1 as the optional arguments or as a keyword
>argument?
>
>There are some built in functions that have both and that trip people
>up sometimes, but I can't remember what they are right now.


I appreciate the quick feedback on this Friday afternoon.

Clearly, I was confused by the spec (CLTL) specifying the syntax of 
the lambda-list -vs- the syntax of the actual run-time call 
especially with keywords specified.

What Howard Ding says above is right (after some thought): 
"...actually makes sense..." because how would the run-time system 
distinguish between a non-keyword argument and a keyword argument.

The only way to make what I wanted to do work would be to have the 
restriction that &optional arguments cannot be :Keywords if they 
might be followed by &key items.

Makes sense...

....an interesting subtlety.


Regards to the List.

Jack Harper
Secure Outcomes Inc
Evergreen, Colorado USA






Updated at: 2020-12-10 08:40 UTC