This mail is going to be long^W thorough. It can be summarized as
follows:
* The matter is a matter of taste. I happen to disagree with the
authors of SBCL (or perhaps CMUCL), as:
* I value sticking to CLHS over The Right Thing on this.
* Compromiss: Make the style-warning its own condition type so it
can be muffled.
First off, in general I really do like SBCL for its noisiness.
Yet, once in a while, I write stuff that have both &OPTIONAL and &KEY
parameters, and I don't find anything unstylish on that as it's a way to
extend an API which deliberates tries to stick to the existing API
modelling decisions made by the standardization group.
So far there has been been three situations where I found &OPTIONAL plus
&KEY the right solution:
a) When writing DO-FOO like macros I do want to model the standard's
"&optional result" interface while still extending on that. I.e. I
often end up defining such a macro as follows
(defmacro do-foo ((var collection &optional result &key k1 k2)
&body body)
...)
Please notice that SBCL does _not_ signal a style-warning in case
&optional and &key appear in a macro lambda list. I do not know
whether or not that's just an omission, or a deliberate strike of
inconsistency in favor of practicality. (If the latter, it supports
my argument.)
b) The functions pertaining to the macro machinery, and the type
system, usually take an optional parameter for the current lexical
environment. Back when I wrote my parse-declarations library, I
wanted to stick to this scheme and I wrote
(defun parse-declarations (decls &optional env &key nostrip)
...)
c) While writing my named-readtables library which deliberately imitates
the package system, I wrote just a moment ago:
(defun make-readtable (&optional name &key merge)
...)
the rationale is that (MAKE-READTABLE) will return an empty
readtable. (It's my opinion that it's a sad omission in the
standard that you cannot create anonymous packages, and _have_ to
provide a name in MAKE-PACKAGE.)
The argument against the combination of &OPTIONAL and &KEY is that it's
easy to miss passing the &optional parameter; e.g.
(READ-FROM-STRING "(ABC" :START 1)
looks innocently correct even though it isn't. It ought to be written as
(READ-FROM-STRING "(ABC" T :START 1).
However, in the presence of supportive development environments---and,
mind you, I'm obviously biased regarding the degree a language should be
joggled to development environments, but nontheless: In the presence of
automatic arglist display (and highlighting of the current parameter), I
can't remember the last time I fell for this allegedly common pitfall.
Regardless of the last point, I think SBCL should rather try to guard
against the fall for the pitfall than trying to eliminate its root which
is subject of taste and hence subject to disagreement ("No, really,
thank you.")
I think, it should signal a style-warning on suspicious call sites
instead:
I've _never_ written, nor seen code, that tries to pass a keyword as an
&optional parameter that _at the same time_ is also a valid &key
parameter. Contrarily, as described above, I've written functions which
combine &optional and &key parameters, and, of course, the standard
contains them, too.
While I tried to be convincing, I don't actually expect this mail to
make you get rid of that style-warning (I _am_ eagerly looking forward
to your side of view, though :-)) --- so how to proceed from here?
Well, luckily, there's an easy technical compromiss: Let's give this
particular style-warning its own condition type instead of the general
simple-style-warning that it is at the moment. Perhaps also make it
inherit from a STYLE-WARNING-OF-TASTE and also make the "implicit
creation of generic function" inherit from that, so people can easily
muffle such style-warnings they don't agree with.
-T.
|