Previous chapter: Functions

Dylan manual: Classes

11. Classes

See Also: Dylan Design Notes: Regularization of the Type System (Change)

See Also Dylan Design Notes: Make Class Specification (Addition)

This section lists additional tools for working with classes and instances. The user should also refer to the introductory section above, where define-class, make, and initialize are described.

<class>	[Abstract Class]
All classes (including <class>) are general instances of <class>. <class> is a subclass of <object>.

The class <class> supports the following init-keywords:

superclasses:
Specifies the superclasses of the class. superclasses: should be a single class or list of classes. The default value is <object>.
debug-name:
Used only for debugging and display purposes. The default is implementation-dependent.
Classes are not normally created by calling to make, but rather through define-class. However, there is nothing to prevent programmers from creating classes by calling make, for example, if they want to create a class without storing it in a module variable.

instance?   object class   ==>  boolean	[Generic Function]
instance? returns true if object is a general instance of class.

Coercing and Copying Objects

These functions are used to perform shallow copies on objects, and to coerce objects to other classes.

as[next citation]   class object   ==>  instance	[Generic Function]
as coerces object to class. That is, it returns a new instance of class that has the same contents as object.

If object is already an instance of class, it is returned unchanged.

Predefined methods allow coercion between numeric types, between integers and characters, and between collection types. No methods are defined for other classes.

When converting between collection types, the new collection (the returned object) will have the same number of elements as the source collection (the object). If the source and target class are both subclasses of <sequence>, the elements will be in the same order. The individual elements may also undergo some conversion.

shallow-copy   object   ==>  new-object	[Generic Function]
shallow-copy returns a new object that has the same contents as object. The contents are not copied but are the same objects contained in object.

The new object is created by calling make on the class-for-copy of object.

Dylan includes methods for copying collections. For other classes, the programmer must provide a method.

class-for-copy[next citation]   object   ==>  class	[Generic Function]
class-for-copy returns the class that should be passed to make in order to duplicate object. The default version calls object-class.

Reflective Operations on Classes

The following operations return information about classes and objects. These functions may be disabled for sealed classes. (Sealing of classes is described in a following section.)

See Also: Dylan Design Notes: Regularization of the Type System (Change)

subclass?   class1 class2   ==>  boolean	[Generic Function]
subclass? returns true if class1 is a subclasseither direct or indirectof class2, or if class1 and class2 are the same class.

object-class   object   ==>  class	[Generic Function]
object-class returns the class of which object is a direct instance.

See Also: Dylan Design Notes: Punt Slot Descriptors (Change)

slot-descriptors   class   ==>  sequence	[Generic Function]
slot-descriptors returns a sequence of the slot descriptors for all the slots in the class. Slot descriptors are described in the following section.

The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior.

all-superclasses   class   ==>  sequence	[Generic Function]
all-superclasses returns all the superclasses of class in a sequence. The order of the classes in the sequence is significant. The first element in the sequence will always be class, and <object> will always be the last.

The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior.

direct-superclasses   class   ==>  sequence	[Generic Function]
direct-superclasses returns the direct superclasses of class in a sequence. These are the classes that were passed as arguments to make or define-class when the class was created. The order of the classes in the sequence is the same as the order in which they were passed to define-class, or make when class was created.

The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior.

See Also Dylan Design Notes: No Incremental Class Modifications (Change)

(setter direct-superclasses)class new-superclass-list  ==>  new-superclass-list
(setter direct-superclasses) remakes class so that it inherits from the classes in new-superclass-list. (You may think youre just setting the value of a slot when you call this generic function. Its actually somewhat more involved than that.)

new-superclass-list is returned. The restrictions on the new-superclass-list are the same as those on the superclasses argument to define-class.

direct-subclasses   class   ==>  sequence	[Generic Function]
direct-subclasses returns the direct subclasses of class in a sequence. These are the classes that have class as a direct superclass. The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior. FN29

Sealing Classes

make-read-only[return to first citation]   class   ==>  class	[Generic Function]
This function makes class read-only, so slots can no longer be added or removed, and the superclasses cannot be changed. This does not affect the instances of the class (i.e., the slots of instances can still be written).

The values of slots in class with class and each-subclass allocation can still be changed.

seal   class   ==>  class	[Generic Function]
seal makes the class read-only and, in addition, new subclasses cannot be created from class. The functions all-superclasses, direct-superclasses, and slot-descriptors will return an empty sequence when called on a sealed class.

Slots and Slot Descriptors

This section gives a low-level description of slots and slot descriptors. Most programs do not need to work with slot descriptors directly. Slot descriptors are created automatically by define-class and define-slot.

The language facilities described in this section can be used in the implementation of the object system. They are useful for inspectors, debuggers, and other system tools, as well as for programs which extend the object system.

<slot-descriptor>	[Abstract Class]
Slot descriptors identify slots and may contain certain information about them (such as default values, specializers, etc.).

<slot-descriptor> is a subclass of <object>.

Slot descriptors are not created directly (with make), but are created and returned by add-slot.

add-slot	slot-owner #key type allocation setter getter 	[Generic Function]
	debug-name init-value init-function init-keyword   
==>  slot-descriptor

add-slot adds a slot to slot-owner (which should be a class or singleton) and returns a slot descriptor for it. The instances of slot-owner are updated to contain the new slot. This function is called by define- class and define-slot.

If the getter and setter are supplied, they should be generic functions. Besides this, all the keyword arguments have the same meanings as in slot-specs of define-class forms.

The debug-name can be retrieved from the slot-descriptor.

If slot-owner is a singleton, then allocation must be instance, constant, or virtual, and init-keyword cannot be specified.

See Also Dylan Design Notes: No Incremental Class Modifications (Change)

remove-slot   slot-owner slot-descriptor   	[Generic Function]
==>  slot-descriptor
remove-slot removes the slot for slot-descriptor from slot-owner. If slot-owner is a class, then existing instances of the class are updated to no longer contain the slot. (The updates do not occur all at once but rather as the objects are accessed.)

slot-descriptor   instance getter   	[Generic Function]
==>  {slot-descriptor or #f}
slot-descriptor returns the slot descriptor for the slot that is accessed in instance by getter. This function works for virtual as well as nonvirtual slots.

slot-descriptor returns #f if getter does not access a slot in instance. It may also return #f if the class of the instance has been sealed.

slot-getter   slot-descriptor   ==>  {generic-function or #f}	[Generic Function]
slot-getter returns the getter generic-function for the slot, or #f if the slot-descriptor indicates a slot in a sealed class. The return value is an actual generic function object, not a variable name.

slot-setter   slot-descriptor   ==>  {generic-function or #f}	[Generic Function]
slot-setter returns the setter generic-function for the slot, or #f if the information is not available. The information will not be available if the slot-descriptor indicates a slot in a sealed class or if no setter was specified or defaulted when the slot was created. The return value is an actual generic function object, not a variable name.

slot-type   slot-descriptor   ==>  {class or singleton}	[Generic Function]
slot-type returns the type restriction of the slot. If no slot type was specified, then the default, <object>, is returned.

slot-allocation   slot-descriptor   ==>  symbol	[Generic Function]
slot-allocation returns a symbol that describes the allocation of the slot.

init-value   slot-descriptor   ==>  object  boolean	[Generic Function]
init-value returns two values: the init-value of the slot and #t if an init-value was specified, or #f and #f if no init-value was specified when the slot was created.

init-function   slot-descriptor   ==>  {function or #f}	[Generic Function]
init-function returns the init-function of the slot, or #f if no init-function was specified when the slot was created.

init-keyword   slot-descriptor   ==>  {keyword or #f}	[Generic Function]
init-keyword returns the init-keyword of the slot, or #f if no init-keyword was specified when the slot was created.

By using a slot-descriptor and an instance, programs can access the storage for slots. The predefined methods on these functions signal an error when passed a slot-descriptor for a slot with virtual allocation, because virtual slots are not backed by any storage.

slot-value   instance slot-descriptor   ==>  object	[Generic Function]
slot-value returns the value of the slot associated with slot-descriptor in instance.

See Also: Dylan Design Notes: Punt Slot Descriptors (Change)

(setter slot-value)   instance slot-descriptor new-value	[Generic Function]
==>  new-value
(setter slot-value) sets the value of the slot associated with slot-descriptor in instance to new-value and returns new-value.

This function enforces the type restrictions specified when the slot was created.

Singletons

Singletons provide a way to add slots and methods to single instances. This let programs specialize a single object, without changing other objects of the same class, and without defining a whole new class just for the object.

Singletons and classes are currently the only types of specializers available in Dylan.

A singleton is little more than a pointer to a single object. The singletons sole purpose is to indicate that object, so that a method can be created that specializes on the object. By defining a method that specializes on a singleton (rather than on a class), you have defined a method that discriminates on the singletons object.

Singleton methods are considered more specific than methods defined on an objects original class. Singletons are the most specific specializer.

Singletons are normally created and used immediately (i.e., passed directly to method, define-method, define-slot, etc.). They are not normally stored for later use.

<singleton>	[Instantiable Class]
The class <singleton> supports the following init-keywords:

object:
The object that the singleton indicates. There is no default for this argument. If it is not supplied, an error will be signaled.
If a singleton for the specified object already exists, implementations are free to fold the two instances into one.

singleton[return to first citation]   object   ==>  singleton	[Function]
singleton returns a singleton for object.

(singleton object) is equivalent to (make <singleton> object: object).

? (define-method double ((thing (singleton 'cup)))
    'pint)
{a method on double}
? (double 'cup)
pint
? (double 10)
20
? (define-method factorial ((num <integer>))
    (* num (factorial (- num 1))))
factorial
? (define-method factorial ((num (singleton 0)))
     1)
factorial
? (factorial 5)
120

Next chapter: Collections