Suppose we want to make a prototype FOO with slots in the list FOO-SLOTS. The :new method has a number of required arguments, which fill the FOO-ARGS slots, and a number of keyword arguments which fill the FOO-KEYS slots. FOO-ARGS and FOO-KEYS together are FOO-SLOTS. We need to write - the prototype definition - the :isnew method - assessor methods - initialization methods Although it is common to put the initializations in the :isnew, I usually write them as separate methods to which :isnew sends messages. Also, because that's the way I am, I do not want to use the same name for the slot, the assessor method, and the default content of the slot (which leads to forms such as (if data (send :data data)) or (if data (slot-value 'data data))). The macros in make-proto.lsp make it relatively easy to do most of this in a standard and error-free way. What we have still have to do "by hand" is to write the initialization methods, which are called :make-foo, where foo is the name of the slot. For the rest we merely say (make-proto foo '(a b) *object*) which leads to (send foo :show) Slots = ((B) (A) (PROTO-NAME . FOO) (INSTANCE-SLOTS AA BB)) Methods = NIL Parents = (#) Precedence List = (# #) and then (make-isnew-method foo (a) (b)) which leads to (send foo :show) Slots = ((B) (A) (PROTO-NAME . FOO) (INSTANCE-SLOTS AA BB)) Methods = ((:ISNEW . #)) Parents = (#) Precedence List = (# #) and finally (make-assessors foo (a b)) which gives us (send foo :show) Slots = ((B) (A) (PROTO-NAME . FOO) (INSTANCE-SLOTS AA BB)) Methods = ((:SET-B . #) (:SET-A . #) (:ISNEW . #)) Parents = (#) Precedence List = (# #) By hand we add (defmeth foo :make-b () nil) and then say (setf foo-instance (send foo :new "alonzo")) which gives (send foo-instance :show) Slots = ((B) (A . "alonzo")) Methods = NIL Parents = (#) Precedence List = (# # #) and we can say (send foo-instance :set-a) which returns "alonzo". Thus for each slot BAR, we have an assessor method :set-bar, which either returns or modifies the slot, and we have a (hand-written) :make-bar which initializes to some sort of default. It would be trivial to add empty :make-bar methods for each bar. The :isnew method puts its arguments in the argument slots, if it has keyword arguments it puts those in the keyword slots, otherwise it fills in the defaults from :make-bar (thus we do not need :make-bar methods if :bar is an argument slot). Along the same lines it is straightforward to make a :save method. --- jan --- 02-22-95