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

Re: Reinitialization: check-initargs

    Date: 28 Apr 88 09:32 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

            From: Danny Bobrow <Bobrow.pa@Xerox.COM>
              (unless (check-keyword-arguments
                    (cons (class-prototype class) initargs)
                    (list #'allocate-instance
                    (class-slot-initargs class))
             (error "illegal initarg"))

        But this doesn't work because each one of allocate-instance,
        initialize-instance, and initialize-new-instance takes slightly
        different arguments.

    Unfortuntately, right.  I have two patches for this, since I think the idea is
    good.  Both patches have problems.  Here are the alternative patches.

    1) The difference in arguments is that #'initialize-instance takes a second
    required argument, slots-using-initforms.  

Also allocate-instance takes a class where the other two take an instance.
I don't remember why we did it that way.

Also update-instance-for-redefined-class and update-instance-for-different-class
should contribute to the initialization argument checking in their respective
cases, but they take idiosyncratic arguments.  If you assume that only the
first argument is specialized by any method (your patch#2 below), the other
arguments could be ignored.  However, that assumption is quite unlikely to
be true for update-instance-for-different-class.

    Instead, make slots-using-initforms be a keyword argument.

This doesn't solve the two problems I mentioned just above.

    2) Change the argument structure for  check-keyword-arguments

    check-keyword-arguments required-arguments
                            &optional extra-allowed-keywords

    Make required arguments be a list that can select the appropriate methods from
    each generic funcion.  If the list is too short, consider it equivalent to being
    filled out with enough nils to be of the right length.

I just got another idea, which is to pass in a list of generic functions
and arguments to which to apply them.  But that doesn't work because we
have forgotten that we are doing check-initargs, not
check-keyword-arguments, and it has to worry about slot-filling initargs
too.  In 88-003 page 60 check-keyword-arguments was used as the name of
an entirely different function that has to do with congruence; let's not
get too confused here.

How about this idea?

  check-initargs class initargs additional-calls

    class - the class whose slot-filling initargs are relevant
    initargs - the list of initargs to be checked
    additional-calls - a list of calls that will be performed;
        each call is a list whose first element is a generic
        function (not the name of a generic function) and whose
        remaining elements are arguments.  Optional/keyword
        arguments can (must?) be omitted from these lists since they do
        not contribute to method applicability.  If any applicable
        method for any call accepts a keyword argument from initargs,
        check-initargs regards that keyword argument as valid.

Thus (see 88-002 p.1-44):

  (defmethod make-instance ((class standard-class) &rest initargs)
    (setq initargs (default-initargs class initargs))
    (check-initargs class initargs
                    `((,#'allocate-instance ,class)
                      (,#'initialize-new-instance ,(class-prototype class))
                      (,#'initialize-instance ,(class-prototype class) t)))
    (let ....

check-initargs's implementation calls method-applicable-keywords
(88-003 p.27) except I believe the name of that function is a typo
and was supposed to be applicable-method-keywords.  [Danny suggested
keywords-for-applicable-methods, that would be okay too.]

88-002 page 1-40 says that (something called by) make-instance signals
an error if an invalid initarg is supplied.  CLtL page 62 says it is
an error if an argument pair has a keyword name not matched by any
parameter specifier.  I am always in favor of argument checking, but
perhaps some of the implementors among us would prefer to make this
complex check-initargs processing an "is an error" situation so that
it can be deleted when compiling for speed.  That's "an error should
be signaled" in 88-002 terminology.

    However, there is a problem in using keywords-for-applicable-methods in
    check-initargs.  What value does it return if &rest or
    &allow-other-keys appears in any method?  

    If we take Moon's suggestion of returning the symbol &allow-other-keys in this
    case, then check-initargs cannnot use this value, since the default
    methods for initialize-instance and allocate-instance have an &rest argument.  

Hold on there.  Read the last paragraph on p.1-29 of 88-002.  &rest has no
effect on the set of acceptable keyword arguments; &rest is not at all
a synonym for &allow-other-keys.  I don't think there is any problem
with keywords-for-applicable-methods returning the symbol &allow-other-keys
when an applicable method has &allow-other-keys in its lambda-list.  This
will correctly cause check-initargs to return without signalling an error.
No predefined CLOS method has &allow-other-keys in its lambda-list.