From: Roman Belenov
Subject: keyword and optional arguments
Date: 
Message-ID: <un0f6y4tc.fsf@yandex.ru>
Is it correct that if function takes both keyword and optional
arguments, optional arguments must precede keyword ones (at least it
is my understanding of CLHS 3.4.1) ? If it is, what is the reason for
this choice ? This way, all optional arguments must be explicitly
specified in order to specify art least one keyword; if other order
was permitted, it would be possible to specify only optional or only
keyword arguments.

-- 
 							With regards, Roman.

Standard disclaimer: I work for them, but I don't speak for them.

From: Thomas A. Russ
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <ymivftus00r.fsf@sevak.isi.edu>
Roman Belenov <·············@intel.com> writes:

> Is it correct that if function takes both keyword and optional
> arguments, optional arguments must precede keyword ones (at least it
> is my understanding of CLHS 3.4.1) ? If it is, what is the reason for
> this choice ? This way, all optional arguments must be explicitly
> specified in order to specify art least one keyword; if other order
> was permitted, it would be possible to specify only optional or only
> keyword arguments.

The reason for this choice is to be able to unambiguosly parse the
argument list.  Otherwise it gets to be a real mess, because all of the
arguments to functions are evaluated, and it is possible that a legal
value of one of the optional arguments is also a keyword.

In general, one should either use optional arguments or keyword
arguments and not mix them.  Mixing them leads to less than optimal
interfaces.  (Yes, I know that READ and other CL functions mix optional
and keyword arguments, but I imagine the optional arguments were there
for backward compatibility).

My preference would be to not use optional arguments at all, but only
keyword arguments.  It makes it much easier to extend the function with
additional arguments later.

By the way, if you really want to have optional and keyword arguments
interspersed, you could always do it yourself.  The function signature
in Lisp would have an &rest argument and then you could process the
optional and keyword arguments yourself.

====

An example of a problematic case for automatic parsing of mixed optional 
and keyword arguments:

(defun f (&optional a &key b)
 (print a)
 (print b))

(let ((k1 :b))
  (f :b k1 3)        Arguments a = :b   b = 3
  (f k1 :b 3)        Arguments a = :b   b = 3
  (f :b)             Arguments a = :b   b = NIL
  )

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Roman Belenov
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <uisptycys.fsf@yandex.ru>
···@sevak.isi.edu (Thomas A. Russ) writes:

> The reason for this choice is to be able to unambiguosly parse the
> argument list.  Otherwise it gets to be a real mess, because all of the
> arguments to functions are evaluated, and it is possible that a legal
> value of one of the optional arguments is also a keyword.

Thanks to you (and all the others) for answers - being a newbie in
Lisp, I just didn't think about keywords passed as normal arguments.

> In general, one should either use optional arguments or keyword
> arguments and not mix them.  Mixing them leads to less than optimal
> interfaces.

Yes, I'll probably follow this advice.

> My preference would be to not use optional arguments at all, but only
> keyword arguments.  It makes it much easier to extend the function with
> additional arguments later.

I also prefer keyword arguments; I felt into this keyword/optional
mixing trap while writing a printing function with some specific
keyword arguments and an output stream which I made optional by
analogy with format or princ.

> By the way, if you really want to have optional and keyword arguments
> interspersed, you could always do it yourself.  The function signature
> in Lisp would have an &rest argument and then you could process the
> optional and keyword arguments yourself.

I see, but it seems that it's easy to make really messy interface with
manual argument list parsing (unless it's more or less uniform), since
no standard rules would apply. 

-- 
 							With regards, Roman.

Standard disclaimer: I work for them, but I don't speak for them.
From: Thomas A. Russ
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <ymiu19es000.fsf@sevak.isi.edu>
Roman Belenov <·············@intel.com> writes:

> Is it correct that if function takes both keyword and optional
> arguments, optional arguments must precede keyword ones (at least it
> is my understanding of CLHS 3.4.1) ? If it is, what is the reason for
> this choice ? This way, all optional arguments must be explicitly
> specified in order to specify art least one keyword; if other order
> was permitted, it would be possible to specify only optional or only
> keyword arguments.

The reason for this choice is to be able to unambiguosly parse the
argument list.  Otherwise it gets to be a real mess, because all of the
arguments to functions are evaluated, and it is possible that a legal
value of one of the optional arguments is also a keyword.

In general, one should either use optional arguments or keyword
arguments and not mix them.  Mixing them leads to less than optimal
interfaces.  (Yes, I know that READ and other CL functions mix optional
and keyword arguments, but I imagine the optional arguments were there
for backward compatibility).

My preference would be to not use optional arguments at all, but only
keyword arguments.  It makes it much easier to extend the function with
additional arguments later.

By the way, if you really want to have optional and keyword arguments
interspersed, you could always do it yourself.  The function signature
in Lisp would have an &rest argument and then you could process the
optional and keyword arguments yourself.

====

An example of a problematic case for automatic parsing of mixed optional 
and keyword arguments:

(defun f (&optional a &key b)
 (print a)
 (print b))

(let ((k1 :b))
  (f :b k1 3)        Arguments a = :b   b = 3
  (f k1 :b 3)        Arguments a = :b   b = 3
  (f :b)             Arguments a = :b   b = NIL
  (f k1)             Arguments a = :b   b = NIL
  )

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Kenny Tilton
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <3F1D595C.4030209@nyc.rr.com>
Roman Belenov wrote:
> Is it correct that if function takes both keyword and optional
> arguments, optional arguments must precede keyword ones 

yep. i never had that sorted out until just now, when i tried to get 
fancy with read-from-string which takes two optional arguents along with 
the keyword arg i wanted to specify.


> If it is, what is the reason for
> this choice ? This way, all optional arguments must be explicitly
> specified in order to specify art least one keyword; if other order
> was permitted, it would be possible to specify only optional or only
> keyword arguments.
> 

that would be nice, but keywords would be valid as optional arguments, 
so if they appeared in that position, that is how they would be construed:

(defun aaa (one &optional two &key three)
   (print (list one two three)))

Now contemplate:

(aaa :one :two :three :four)
=> (:ONE :TWO :FOUR)

(aaa :one :three :three :two)
=> (:ONE :THREE :TWO)



-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Everything is a cell." -- Alan Kay
From: Barry Margolin
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <zYcTa.323$0z4.130@news.level3.com>
In article <·············@yandex.ru>,
Roman Belenov  <·············@intel.com> wrote:
>Is it correct that if function takes both keyword and optional
>arguments, optional arguments must precede keyword ones (at least it
>is my understanding of CLHS 3.4.1) ? 

Yes.

>				      If it is, what is the reason for
>this choice ?

Because it can be ambiguous otherwise.  Suppose you have a function like:

(defun fun (&optional opt1 opt2 &key key) 
  (list opt1 opt2 key1))

and the call is:

(fun :key 'value)

Should this return (NIL NIL VALUE) or (:KEY VALUE NIL)?

-- 
Barry Moptolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <sfwr84idyxn.fsf@shell01.TheWorld.com>
Roman Belenov <·············@intel.com> writes:

> Is it correct that if function takes both keyword and optional
> arguments, optional arguments must precede keyword ones (at least it
> is my understanding of CLHS 3.4.1) ? If it is, what is the reason for
> this choice ? This way, all optional arguments must be explicitly
> specified in order to specify art least one keyword; if other order
> was permitted, it would be possible to specify only optional or only
> keyword arguments.

This is the reason, incidentally, for the famous READ-FROM-STRING
error in which people write
 (read-from-string :start 3)
and wonder why it doesn't start in the place they expect.

I believe in Dylan you can specify only optional or keyword arguments,
but not both.  I think that'd have been better design--but, alas, we
didn't have years of experience with another popular dynamic language to 
learn from before doing our design...
From: Kent M Pitman
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <sfwu19em3w6.fsf@shell01.TheWorld.com>
Kent M Pitman <······@world.std.com> writes:

> Roman Belenov <·············@intel.com> writes:
> 
> > Is it correct that if function takes both keyword and optional
> > arguments, optional arguments must precede keyword ones (at least it
> > is my understanding of CLHS 3.4.1) ? If it is, what is the reason for
> > this choice ? This way, all optional arguments must be explicitly
> > specified in order to specify art least one keyword; if other order
> > was permitted, it would be possible to specify only optional or only
> > keyword arguments.
> 
> This is the reason, incidentally, for the famous READ-FROM-STRING
> error in which people write
>  (read-from-string :start 3)
> and wonder why it doesn't start in the place they expect.

Er, (read-from-string "foobar" :start 3) I mean.  I left out the string,
which would have changed the parity of the number of args, and probably
would have been noticed in a way that this one wouldn't be by a good
compiler.  (I noticed this right after I sent it, but figured a billion 
people would correct me.  Since none have, I guess I might as well correct
myself...)

> I believe in Dylan you can specify only optional or keyword arguments,
> but not both.  I think that'd have been better design--but, alas, we
> didn't have years of experience with another popular dynamic language to 
> learn from before doing our design...
From: Steven M. Haflich
Subject: Re: keyword and optional arguments
Date: 
Message-ID: <3F1D7758.6030707@alum.mit.edu>
Many believe that it is simlpy bad API design to use both optional
and keyword arguments in the same function.  The several examples in
the ANS were retained for back compatibility, but there is little
reason to invent new functions with this builtin hazard.