[4/19/99] =============================================================================== * General questions about defclass. The complete syntax definition from swindle.txt is below. Comments: - The difference between initvalue and initiaqlizer should be clear. - The :reader and :writer options create generic functions that you can override like any other generic function. - The :accessor option creates two methods as foo and foo-set!. These methods can also be extended easily. foo-set! is the actual method used for expressions like (set! (foo x) y). - If one of these names is already defined as a generic, then the new method should be able to be added to the generic. For example: -------------------- (defmethod (foo x y z) (+ x y z)) (defclass () (foo :accessor foo)) --> add-method: wrong number of specializers for foo, expects 3; given 1. -------------------- :type specifies the slot type. Only values of the specified type can be put in this slot. :initarg specifies a keyword argument, so if it is given to make, will be used to initialize this slot's value. This will override :initvalue and :initializer. Can be more than one value by inheritance. :initializer the given value should be a function, that gets a single value and return an init value. The value that it will receive is the argument list given to make. This value takes precedence over a given :initvalue. :initvalue specifies an initial value for this slot. Note that checking the type is only on creation of instances. :allocation specifies the allocation of this slot, :instance is a normal slot, and :class is a slot that is shared among all instances of the class. :reader specifies a name that will be bound to a reader function for this slot. :writer specifies a name that will be bound to a writer function for this slot. :accessor specifies a name that will be bound to an accessor function for this slot - it can be used as a reader, and also with a setf! or setv! forms. =============================================================================== * Note about lambda expression. A normal lambda expression returns a simple procedure (of type ). It is possible to add a type to one of the arguments, giving you a object that is used in the same way as a procedure excpt it will check its arguments. Now, since define forms with a list as the object being defined are translated into a define of the symbol ad a lambda expression, then these two expressions are equivalent: -------------------- (define f (lambda ((x )) 1)) (define (f (x )) 1) -------------------- This is _different_ from a defmethod expression - if you will enter these two expressions: -------------------- (define (f (x )) 1) (define (f (x )) 2) -------------------- then the second definition redefines f, and the first method is lost. This is very different from defmehod. Every generic function object contains a list of methods, when you write a defmethod expression, a method will be created, and then this method will get added to the generic function which is actually doing work by side effect, so this makes it very different from define forms. Note that because defmethod is actually doing the side-effect of modifying the list of methods stored in a generic function object, then it doesn't make sence to call defmethod from inside functions. When a method is being added to a generic, the list of curret methods is being examined and any existing method that has the same exact specializers will get replaced by the new method, for example, in: -------------------- (defmethod (foo (x )) 1) (defmethod (foo (x )) 2) (define ) (defmethod (foo (x )) 3) -------------------- the last defmethod overrides the method created by the first. [Note - defmethod will actually define a generic function object if it is not defined, and then add the method object to it.] ===============================================================================