Object Oriented Programming

The structures and behaviors of objects are described in classes, which are defined by defclass macro and defmethod special form. defclass defines the name of the class, its super class, and slot variable names, optionally with their types and message forwarding. defmethod defines methods which will invoked when corresponding messages are sent. Class definition is assigned to the symbol's special value. You may think of class as the counter part of Common Lisp's structure. Slot accessing functions and setf methods are automatically defined for each slot by defclass.

Most classes are instantiated from the built-in class metaclass. Class vector-class, which is a subclass of metaclass, is a metaclass for vectors. If you need to use class-variables and class-methods, you may make your own metaclass by subclassing metaclass, and the metaclass name should be given to defclass with :metaclass keyword.

Vectors are different from other record-like objects because an instance of the vector can have arbitrary number of elements, while record-like objects have fixed number of slots. EusLisp's object is either a record-like object or a vector, not both at the same time.

Vectors whose elements are typed or the number of elements are unchangeable can also be defined by defclass. In the following example, class intvec5 which has five integer elements is defined. Automatic type check and conversion are performed when the elements are accessed by the interpreter. When compiled with proper declaration, faster accessing code is produced.

(defclass intvec5 :super vector :element-type :integer :size 5)
(setq x (instantiate intvec5))  --> #i(0 0 0 0 0)

When a message is sent to an object, the corresponding method is searched for, first in its class, and next in its superclasses toward object, until all superclasses are exhausted. If the method is undefined, forward list is searched. This forwarding mechanism is introduced to simulate multiple inheritance. If the search fails again, a method named :nomethod is searched, and the method is invoked with a list of all the arguments. In the following example, the messages :telephone and :mail are sent to secretary slot object which is typed person, and :go-home message is sent to chauffeur slot.

(defclass president :super object
                    :slots ((name :type string)
                            (age  :type :integer)
                            (secretary  :type person
                                        :forward (:telephone :mail))
                            (chauffeur  :forward (:go-home))))

In a method, two more local variables, class and self, become accessible. You should not change either of these variables. If you do that, the ones supplied by the system are hidden, and send-super and send self are confused.

Classes and Methods

defclass classname &key :super object [macro] 

:slots ({var $ \vert$ (var [:type type] [:forward selectors])}*)
:metaclass metaclass
:element-type t
:size -1
creates or redefine a class. When a class is redefined to have different superclass or slot variables, old objects instantiated from the previous class definition will behave unexpectedly, since method definitions assume the new slots disposition.

defmethod classname {(selector lambda-list . body)}* [special]

defines one or more methods of classname. Each selector must be a keyword symbol.

defclassmethod classname {(selector lambda-list . body)}* [macro]

classp object [function]

T if object is a class object, that is, an instance of class metaclass or its subclasses.

subclassp class super [function]

Checks class is a subclass of super.

vector-class-p x [function]

T if x is an instance of vector-class.

delete-method class method-name [function]

The method definition is removed from the specified class.

class-hierarchy class [function]

prints inheritance hierarchy below class.

system:list-all-classes [function]

lists up all the classes defined so far.

system:find-method object selector [function]

tries to find a method specified by selector in the class of object and in its superclass. This is used to know whether object can respond to selector.

system:method-cache [flag] [function]

Interrogates the hit ratio of the method cache, and returns a list of two numbers, hit and miss. If flag is NIL, method caching is disabled. If non-nil flag is given, method cache is purged and caching is enabled.

Message Sending

send object selector {arg}* [function]

send a message consisting of selector and arg to object. object can be anything but number. selector must be evaluated to be a keyword.

send-message target search selector {arg}* [function]

Low level primitive to implement send-super.

send* object selector &rest msg-list [macro]

send* applies send-message to a list of arguments. The relation between send and send* is like the one between funcall and apply, or list and list*.

send-all receivers selector &rest mesg [function]

sends the same message to all the receivers, and collects the result in a list.

send-super selector &rest msgs [macro]

sends msgs to self, but begins method searching at the superclass of the class where the method currently being executed is defined. It is an error to send-super outside a method (i.e. in a function).

send-super* selector &rest msg-list [macro]

send-super* is apply version of send-super.

Instance Management

instantiate class &optional size [function]

the lowest primitive to create a new object from a class. If the class is a vector-class, size should be supplied.

instance class &rest message [macro]

An instance is created, and the message is sent to it.

make-instance class &rest var-val-pairs [function]

creates an instance of class and sets its slot variables according to var-val-pairs. For example, (make-instance cons :car 1 :cdr 2) is equivalent to (cons 1 2).

copy-object object [function]

copy-object function is used to copy objects keeping the referencing topologies even they have recursive references. Copy-object copies any objects accessible from object except symbols and packages, which are untouched to keep the uniqueness of symbols. copy-object traverses all the references in an object twice: once to create new objects and to mark original objects that they have already copied, and again to remove marks. This two-step process makes copy-object work slower than copy-seq. If what you wish to copy is definitely a sequence, use of copy-seq or copy-tree is recommended.

become object class [function]

changes the class of object to class. The slot structure of both the old class and the new class must be consistent. Usually, this can be safely used only for changing class between binary vectors, for example from an integer-vector to a bit-vector.

replace-object dest src [function]

dest must be an instance of the subclass of src.

class object [function]

returns the class object of object. To get the name of the class, send :name message to the class object.

derivedp object class [function]

derivedp checks if an object is instantiated from class or class's subclasses. subclassp and derivedp functions do not search in class hierarchy: type check always finishes within a constant time.

slot object class (index $ \vert$ slot-name) [function]

Returns the named or indexed slot value.

setslot object class (index $ \vert$ slot-name) value [function]

Setslot is a internal function and users should not use it. Use, instead, combination of setf and slot.

Basic Classes

object [class]



Object is the most basic class that is located at the top of class hierarchy. Since it defines no slot variables, it is no use to make an instance of object.

:prin1 &optional stream &rest mesg [method]

prints the object in the standard re-readable object format, that is, the class name and the address, enclosed by angle brackets and preceded by a pound sign. Any subclasses of object can use this method to print itself with more comprehensive information by using send-super macro specifying mesg string. An object is re-readable if it begins with #$ <$, followed by its class name, correct address, any lisp-readable information, and >. Since every data object except numbers inherits object, you can get print forms in this notation, even for symbols or strings. Specifying this notation, you can catch data objects that you forgot to setq to a symbol, as long as there happened no garbage collection after it is printed.

:slots [method]

returns the list of variable-name and value pair of all the slots of the object. You can get the value of a specific slot by applying assoc to this list, although you cannot alter them.

propertied-object [class]

  :super   object 

:slots plist

defines objects that have property list. Unlike other Common Lisp, EusLisp allows any objects that inherit propertied-object to have property lists, even if they are not symbols.

:plist &optional plist [method]

if plist is specified, it is set to the plist slot of this object. Previous plist, if there had been one, is lost. Legal plist should be of the form of ((indicator1 . value1) (indicator2 . value2) ...). Each indicator can be any lisp form that are tested its equality with the eq function. When a symbol is used for an indicator, use of keyword is recommended to ensure the equality check will be performed interpacakge-widely. :plist returns the current plist.

:get indicator [method]

returns the value associated with indicator in the property list. (send x :get :y) == (cdr (assoc :y (send x :plist))).

:put indicator value [method]

associates value to indicator in the plist.

:remprop indicator [method]

removes indicator and value pair from the plist. Further attempt to :get the value returns nil.

:name &optional name [method]

defines and retrieves the :name property in the plist. This property is used for printing.

:prin1 &optional stream &rest mesg [method]

prints the object in the re-readable form. If the object has :name property, it is printed after the address of the object.

:slots [method]

returns a list of variable and value pairs of this object.

:methods [method]

returns a list of all method names defined for this object. In other words, this object can accept method calls listed by :methods.

:get-val variable-name [method]

returns the value of the slot designated by variable-name. If the object does not have the variable-name slot, an error is reported.

:set-val variable-name value [method]

sets value in the variable-name slot of this object. If the object does not have the variable-name slot, an error is reported.

metaclass [class]

  :super   propertied-object 

:slots name super cix vars types forwards methods

Metaclass defines classes. Classes that have own class variables should be defined with metaclass as their superclass.

:new [method]
creates an instance of this class and returns it after filling all the slots with NIL.

:super [method]
returns the super class object of this class. You cannot alter superclass once defclassed.

:methods [method]
returns a list of all the methods defined in this class. The list is composed of lists each of which describes the name of the method, parameters, and body.

:method name [method]
returns the method definition associated with name. If not found, NIL is returned.

:method-names subname [method]
returns a list of all the method names each of which contains subname in its method name. Methods are searched only in this class.

:all-methods [method]
returns a list of all methods that are defined in this class and its all the super classes. In other words, an instance of this class can execute each of these methods.

:all-method-names subname [method]
returns a list of all the method names each of which matches with subname. The search is made from this class up to object.

:slots [method]
returns the slot-name vector.

:name [method]
returns the name symbol of this class.

:cid [method]
returns an integer that is assigned to every instance of this class to identify its class. This is an index to the system-internal class table, and is changed when a new subclass is defined under this class.

:subclasses [method]
returns a list of the direct subclass of this class.

:hierarchy [method]
returns a list of all the subclasses defined under this class. You can also call the class-hierarchy function to get a comprehensive listing of all the class hierarchy.

find-method object selector [function]
searches for the method identified by selector in object's class and its super classes. This function is useful when object's class is uncertain and you want to know whether the object can handle the message without causing nomethod error.

Travis CI User 2017-03-07