From: ···@maui.cs.ucla.edu
Subject: Are optional arguments required?
Date: 
Message-ID: <15115@shemp.CS.UCLA.EDU>
There seems to be at least one case where &optional arguments are actually
required.  Here is a simple function I was trying to define:

    (defun test-args (req1 &optional (opt1 'opt1)
			   &key (key1 'key1)
			   (key2 'key2))
      (format t "Arguments:~%~%")
      (format t "REQ1:  ~A~%" req1)
      (format t "OPT1:  ~A~%" opt1)
      (format t "KEY1:  ~A~%" key1)
      (format t "KEY2:  ~A~%" key2)
      (format t "~%")
      (values))

Seems fine so far.  Now, when you call TEST-ARGS with arguments

	1 2 :key1 3

everything is fine.  However, arguments

	1 :key1 2

result in an error.  The optional argument must be supplied before the
keyowrd arguments.  In CLtL, the examples of the mixtures of different
types of arguments never showed a case where &optional was NOT supplied and
&key was used.  It also follows the description of the argument processing
in CLtL.  However, doesn't this defeat the purpose for &optional arguments?

From: Rob Pettengill
Subject: Re: Are optional arguments required?
Date: 
Message-ID: <1016@perseus.SW.MCC.COM>
In article <·····@shemp.CS.UCLA.EDU> ···@CS.UCLA.EDU (Leonid V. Belyaev) writes:
;There seems to be at least one case where &optional arguments are actually
;required.  Here is a simple function I was trying to define:
;
;    (defun test-args (req1 &optional (opt1 'opt1)
;			   &key (key1 'key1)
;			   (key2 'key2))
;      (format t "Arguments:~%~%")
;      (format t "REQ1:  ~A~%" req1)
;      (format t "OPT1:  ~A~%" opt1)
;      (format t "KEY1:  ~A~%" key1)
;      (format t "KEY2:  ~A~%" key2)
;      (format t "~%")
;      (values))
;
;Seems fine so far.  Now, when you call TEST-ARGS with arguments
;
;	1 2 :key1 3
;
;everything is fine.  However, arguments
;
;	1 :key1 2
;
;result in an error.  The optional argument must be supplied before the
; ...

When an optional argument beyond the first one is to be supplied then
all of the preceeding optional arguments must be supplied.  In order
to avoid ambiguity in the interpretation of the values passed, all
optional arguments must be specified before keyword arguments when
both are passed.  Zetalisp used to distinquish between required and
optional keyword arguments - Common Lisp has only optional keyword
arguments.  Read the description of lambda list processing in Section
5.2.2 (page 61).  All optional parameters are bound before any keyword
parameters are bound.  This is exactly the behavior you describe.

;rob
From: Barry Margolin
Subject: Re: Are optional arguments required?
Date: 
Message-ID: <25537@think.UUCP>
In article <·····@shemp.CS.UCLA.EDU> ···@CS.UCLA.EDU (Leonid V. Belyaev) writes:
>    (defun test-args (req1 &optional (opt1 'opt1)
>			   &key (key1 'key1)
>			   (key2 'key2))
>
>Seems fine so far.  Now, when you call TEST-ARGS with arguments
>
>	1 2 :key1 3
>
>everything is fine.  However, arguments
>
>	1 :key1 2
>
>result in an error.

This is true.  All "positional" arguments must be specified before
any keyword arguments.

The reason is that a keyword is a perfectly valid value for an
optional argument.  So, in your second call, REQ1 is given the value
1, OPT1 is given the value :KEY1, and then it tries to parse the rest
of the arguments as keyword arguments, which results in the error you
got.

There's no way to get rid of this restriction except by making
keywords invalid as values for optional arguments, which is a very
unlikely thing to happen.

>However, doesn't this defeat the purpose for &optional arguments?

Not really.  Consider a function that has two optional arguments.  You
can't supply the second optional argument without supplying the first.
This doesn't defeat the purpose of making the first one optional,
although it is somewhat less convenient.  The programmer has decided
that a caller that needs to specify the second optional argument is
likely to want to specify the first, too.

Think of the keywords as a set of "last" optional arguments, which may
be in any order among themselves.

In general, I think it is poor style to have both &optional and &key
arguments.  Any function that has more than about three optional
arguments should probably make them all &key.  The whole point of &key
arguments is to solve the problem where the caller only wants to
specify some of the optional arguments.


Barry Margolin
Thinking Machines Corp.

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