[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
(DEFUN FOO (&OPTIONAL STREAM ...)
(IF (NOT STREAM) (SETQ STREAM *STANDARD-OUTPUT*))
or (DEFUN FOO (&OPTIONAL (STREAM *STANDARD-OUTPUT*) ...)
The latter may seem to be implied, but in my experience, the former
implementation is much more robust since it allows one to simply write
NIL when they only want to specify a later variable. eg, if I only want
to supply a second argument of 3, I can write:
(FOO NIL 3)
to match the first implementation, but must write:
(FOO *STANDARD-OUTPUT* 3)
if the implementation is the second. In cases where the default is computed
in some hairy and/or private way, the situation complicates considerably.
Sometimes, the actual implementation may even have been driven by irrelevant
issues like whether the arglist was `getting too cluttered' and the writer
may have just taken the initialization down in the body to `pretty
things up' without really thinking out what the semantic effect of that
change would be.
The argument for &KEY is similar. It may turn out that you want to define
a function DELQ as per Maclisp. Two possible implementations present themselves:
(DEFUN DELQ (THING LIST &OPTIONAL COUNT)
(DELETE THING LIST :TEST #'EQ :COUNT COUNT))
(DEFUN DELQ (THING LIST &OPTIONAL (COUNT NIL COUNT-P))
(APPLY #'DELETE THING LIST :TEST #'EQ (IF COUNT-P (LIST :COUNT COUNT) '())))
Personally, I think the former is more perspicuous, but it can only be written
if we define that it is acceptable for DELETE to take a :COUNT argument of NIL.
If the definition of DELETE is left as vague as it is now, only the second
implementation of DELQ above will be portable.
This issue is obviously more general than just DELETE.
My conclusions from all this are as follows:
* The manual is simply ambiguous on this point currently and unless someone can
cite a definitive passage, I guess we'll have to resign ourselves to this not
* Wherever it is possible to get some concensus, I think we should strive to
make passing a keyword of NIL be the same as not passing a keyword. There
will be cases where this will not be possible, so I am not suggesting that
this be an across the board thing -- but I think it can usefully be handled
on a case-by-case basis. :COUNT, :TEST, and :TEST-NOT keywords are good places
to start, however, since there could be no confusion about whether the NIL
was intended as a valid argument. Things like :VERBOSE would not be candidates
since NIL is already valid as an explicit argument.
* Where there is no concensus, or where we agree that passing a keyworded value
of NIL is different than passing no argument, the manual should clearly indicate