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

Re: Reinitialization: check-initargs



There hasn't been any more mail, so I suggest we go with this.
Anyone who objects should do so soon, right?

Note that part of what Danny is proposing here is to eliminate
the special-purpose function check-initargs, which was only for
initialization arguments, and replace it with a general purpose
function check-keyword-arguments that can be used in any situation
involving multiple generic functions accepting a common set of
keyword arguments.  Initialization arguments are probably the only
such situation among the predefined functions of CLOS, but users
might define similar protocols in their own programs.

Sonya suggests that since this is a general purpose function, it
should be written up in chapter 2.  I agree.  The implementation
of this function involves calling chapter 3 functions, but callers
of the function don't need to understand the implementation.

    Date: 29 Apr 88 19:07 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    check-keyword-arguments keyword-arguments
                            generic-functions-and-arguments
                            &optional extra-allowed-keywords

    keyword-arguments is a p-list of keyword arguments to be passed to the
    generic-functions in generic-functions-and-arguments.

    generic-functions-and-arguments is a list of lists, each containing a generic
    function followed by a list of the required arguments that can select
    appropriate methods. 

    extra-allowed-keywords is a list of additional allowed keywords.

    make instance would call check-keyword-arguments this way

    (defmethod make-instance ((class standard-class) &rest initargs)
      (setq initargs (default-initargs class initargs))
      (let ((proto (class-prototype class)))
        (unless (check-keyword-arguments
                  initargs
                  (list (list #'allocate-instance class)
                        (list #'initialize-instance proto nil)
                        (list #'initialize-new-instance proto))
                  (class-slot-initargs class))
          (error "illegal initarg")))
      .
      .
      .)

There remains a problem with how to report an error.  Danny proposes
that check-keyword-arguments simply returns t or nil, and the caller
must report the error.  As you can see from the above example, that
tends to result in a poor error message, since the caller has no easy
way to find out which initarg(s) is/are invalid.  On the other hand,
if check-keyword-arguments reports the error itself, it has no way
to find the context; it could say ":FOO is an invalid argument" but
it could not say ":FOO is an invalid initialization argument for the
class MUMBLE".

One way out of this would be for check-keyword-arguments to report
the error, with the caller supplying an additional argument that is
a string included in the error message to provide context.

I believe a more correct solution is to use the condition handling
system that has been proposed for Common Lisp but not yet adopted.
check-keyword-arguments should report the error itself, using a
specific condition with a name like invalid-keyword-arguments.
Callers that wish to supply additional context should use
HANDLER-BIND to capture the condition and resignal a condition
that encapsulates the original one and reports an error message
combining information from the two sources.  The immediate implication
for CLOS is that check-keyword-arguments should signal the error
itself, and the call in MAKE-INSTANCE should ignore the returned
value.  We can omit the potential use of HANDLER-BIND by MAKE-INSTANCE
from the CLOS spec.  The returned value of check-keyword-arguments
should be documented to be the first argument.

    As for the check-keyword-arguments on page 60 of Chapter 3, it is the one that
    is misnamed.  It should be called something more like
    check-method-keyword-arguments.

Okay.