[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
check-keyword-arguments
Date: 19 May 88 1613 PDT
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>
I want to present one more alternative to the initargs checking
problem.
[Getting rid of check-initargs & successors, writing the code inline,
and putting it in chapter 3.]
This sounds good to me, with a couple modifications suggested below.
Let's go with it.
We could introduce a new generic function called valid-keywords, which
takes an object; if it is something with keywords (like a generic
function, a method, or a function), valid-keywords returns two values: a
list of the explicitly named keywords and a boolean which states whether
&allow-other-keys had been specified in the definition.
function-keywords would be a better name. Otherwise okay.
I have no quarrel with the dual return values.
[Yes, I know (subtypep 'method 'function) => nil t. Nonetheless,
in this context the method is used in a functionesque way.]
I assume method-applicable-keywords, p.27 of the most recent draft
of ch.3 that I've seen (the one handed out at X3J13 in March), would
go away.
Then we could write make-instance like this:
(defmethod make-instance ((class standard-class) &rest initargs)
(setq initargs (default-initargs class initargs))
(let* ((proto (class-prototype class))
(methods
(union
(compute-applicable-methods #'allocate-instance `(,class))
(union
(compute-applicable-methods #'initialize-instance `(,proto nil))
(compute-applicable-methods #'shared-initialize `(,proto))))))
I think you want append rather than union, since there won't be any
methods in common between distinct generic functions. Also the args for
initialize-instance and shared-initialize have accidentally gotten
interchanged.
(unless
(subsetp
(let ((keys '()))
(do ((plist initargs (cddr plist)))
((null plist) keys)
(push (car plist) keys)))
(union
(class-slot-initargs class)
(reduce #'union (mapcar #'valid-keywords methods))))
(error ...)))
(let ((instance (apply #'allocate-instance class initargs)))
(apply #'initialize-instance instance initargs)
instance))