[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[no subject]



	(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))

and

	(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
   being defined.

 * 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
   such.