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

Re: proposed syntactic cleanups in defmethod

Proposal 1:

> I propose that the DEFMETHOD macro be specified to "refer to" (in the
> sense of CLtL p.160) each specialized parameter.  This means that a
> compiler warning will not occur regardless of whether the body of the
> method does or does not refer to the parameter, 

I support this proposal. I think a good case was made for it.

Proposal 2:

> So I'd like to see the syntax of an individual
> parameter-specializer-name changed to use a different word instead of
> QUOTE, and to use a form that evaluates to the object, instead of the
> object itself.  The form is evaluated at the time the method is defined;
> it is not evaluated each time the generic function is called.  I have
> two suggestions for what word to use, one based on what test is being
> performed and the second based on the Common Lisp type system:

I feel vaguely uneasy about this proposal. Part of the reason is because,
as rpg more forcefully stated somewhat earlier, I do not much like the idea 
of having quoted objects as specializers in the first place. 

The reason for this is as follows. One could view quoted objects as being
a kind of restricted subrange type. Allowing quoted objects means that users 
can define methods which discriminate on individual FIXNUMs or arrays, but
disallowing subranges means they can't define methods which discriminate on
all FIXNUMs or arrays of a particular size. 

One could argue that this is rather an argument for allowing subranges than for
disallowing quoted objects, but I believe that subranges are a distinctly
different kind of thing. In fact, subranges are a kind of type
parameterization, since certain parameters must be supplied at the time the
type is instantiated (as opposed to when an instance is created) and these
parameters are usually of a nature which constrain instances in some manner.
Following through on the FIXNUM example, FIXNUMs can be viewed as an
instance of a more general type, RESTRICTED-INTEGER, which requires a
parameter indicating upper and lower bounds on the size of instances.
Similarly, an individual FIXNUM can be viewed as a member of the type (EQL x).

That said, I think Moon's ADDITIONAL-MAIL-HEADER example:

>   (defmethod additional-mail-headers ((host 'xerox.com))
>     '(:line-fold "No"))

indicates how quoted objects as specifiers might be useful. But one could
just as well write:

    (defmethod additional-mail-headers ((host symbol))

        (case host

            .... ;;various other possibilites

         ( 'xerox.com '(:line-fold "No") )))

Embedded CASE statements suffer the disadvantage that, when changes are
made (for example, adding a new host), then an additional branch must
be added or deleted everywhere. But, with quoted objects as parameter 
specifiers, adding an additional case requires adding new method 
definitions anyway, so I have trouble seeing any gain as opposed to the 
loss of consistency cited above. 

Classes could be used to generalize the mail example:

	(defclass host-name ()
		:type symbol 
		:accessor NIL 
		:initform NIL
           (:reader-prefix NIL))

	(defmethod print-object ((object host-name) stream)
	  (print (name object) stream))

	;;;Various other methods for dealing with host names

        (defmethod additional-mail-headers ((host host-name))

           (case (name host)

            .... ;;various other possibilites

             ( 'xerox.com '(:line-fold "No") )))

Modifications to the host tables would still require adding another branch
to all CASEs, but methods operating on instances of HOST-NAME are likely
to be grouped together, and thus the difference between modifying a CASE
and adding an additional method is not large. After all, I don't think the
point of CLOS was to completely eliminate the need for CASE statements, but
rather to provide users a way of constructing code with generalizes
behaviors and structures.

So I'd actually prefer to eliminate quoted objects entirely.

> I mildly prefer EQL over MEMBER, but I thought I'd open up both
> suggestions for discussion.  Each of these suggests an obvious
> generalization, EQL to other predicates and MEMBER to multiple
> individuals, and the choice might be based on which generalization we
> want people to think about, even if we don't propose to implement the
> generalization.

If the above arguments don't sound convincing, or people just don't have
the energy and want to stick with what we already have, then I'd prefer
introducing some kind of new symbol, rather than using either of these.
The reason is because I'd rather avoid having people generalize, since
either of the generalizations lead in directions which I don't think
we're prepared to address. Something like SINGELTON would be a possibility:

  (defmethod additional-mail-headers ((host (singleton (parse-host "xerox.com"))))
	'(:line-fold "No"))

Proposal 3:

> The final issue has to do with parameter-specializers rather than
> parameter-specializer-names, using the terminology of 87-002 page 1-18.
> I think that adding QUOTE as a type-specifier to Common Lisp is both
> unnecessary and confusing.  (Yes, I know I suggested it.  I was wrong.)

I agree with this (modulo my misgivings about quoted objects as
specializers in the first place); however, again I think that some specific
other symbol (like SINGLETON) would be more appropriate.