29.10. Slot Access
Prev | Chapter 29. Meta-Object Protocol | Next

## 29.10. Slot Access

### 29.10.1. Instance Structure Protocol

The instance structure protocol is responsible for implementing the behavior of the slot access functions like `SLOT-VALUE` and `(`SETF` `SLOT-VALUE`)`.

For each CLOS slot access function other than `SLOT-EXISTS-P`, there is a corresponding generic function which actually provides the behavior of the function. When called, the slot access function finds the pertinent effective slot definition metaobject, calls the corresponding generic function and returns its result. The arguments passed on to the generic function include one additional value, the class of the `object` argument, which always immediately precedes the `object` argument.

Table 29.6. The correspondence between slot access function and underlying slot access generic function

Slot Access Function | Corresponding Slot Access Generic Function
--- | ---
`SLOT-VALUE` `object` `slot-name` | `CLOS:SLOT-VALUE-USING-CLASS` `class` `object` `slot`
`(`SETF` `SLOT-VALUE`)` `new-value` `object` `slot-name` | `(SETF CLOS:SLOT-VALUE-USING-CLASS)` `new-value` `class` `object` `slot`
`SLOT-BOUNDP` `object` `slot-name` | `CLOS:SLOT-BOUNDP-USING-CLASS` `class` `object` `slot`
`SLOT-MAKUNBOUND` `object` `slot-name` | `CLOS:SLOT-MAKUNBOUND-USING-CLASS` `class` `object` `slot`

At the lowest level, the instance structure protocol provides only limited mechanisms for portable programs to control the implementation of instances and to directly access the storage associated with instances without going through the indirection of slot access. This is done to allow portable programs to perform certain commonly requested slot access optimizations.

In particular, portable programs can control the implementation of, and obtain direct access to, slots with allocation `:INSTANCE` and type `T`. These are called directly accessible slots.

The relevant specified around-method on `CLOS:COMPUTE-SLOTS` determines the implementation of instances by deciding how each slot in the instance will be stored. For each directly accessible slot, this method allocates a location and associates it with the effective slot definition metaobject. The location can be accessed by calling the `CLOS:SLOT-DEFINITION-LOCATION` generic function. Locations are non-negative integers. For a given class, the locations increase consecutively, in the order that the directly accessible slots appear in the list of effective slots. (Note that here, the next paragraph, and the specification of this around-method are the only places where the value returned by `CLOS:COMPUTE-SLOTS` is described as a list rather than a set.)

Given the location of a directly accessible slot, the value of that slot in an instance can be accessed with the appropriate accessor. For `STANDARD-CLASS`, this accessor is the function `CLOS:STANDARD-INSTANCE-ACCESS`. For `CLOS:FUNCALLABLE-STANDARD-CLASS`, this accessor is the function `CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS`. In each case, the arguments to the accessor are the instance and the slot location, in that order. See the definition of each accessor for additional restrictions on the use of these function.

Portable programs are permitted to affect and rely on the allocation of locations only in the following limited way: By first defining a portable primary method on `CLOS:COMPUTE-SLOTS` which orders the returned value in a predictable way, and then relying on the defined behavior of the specified around-method to assign locations to all directly accessible slots. Portable programs may compile-in calls to low-level accessors which take advantage of the resulting predictable allocation of slot locations.

This example shows the use of this mechanism to implement a new class metaobject class, `ordered-class` and class option `:SLOT-ORDER`. This option provides control over the allocation of slot locations. In this simple example implementation, the `:SLOT-ORDER` option is not inherited by subclasses; it controls only instances of the class itself.

    (defclass ordered-class (standard-class)
      ((slot-order :initform ()
                   :initarg :slot-order
                   :reader class-slot-order)))

    (defmethod compute-slots ((class ordered-class))
      (let ((order (class-slot-order class)))
        (sort (copy-list (call-next-method))
              #'(lambda (a b)
                  (< (position (slot-definition-name a) order)
                     (position (slot-definition-name a) order))))))

Following is the source code the user of this extension would write. Note that because the code above does not implement inheritance of the `:SLOT-ORDER` option, the function `distance` must not be called on instances of subclasses of `point`; it can only be called on instances of `point` itself.

    (defclass point ()
      ((x :initform 0)
       (y :initform 0))
      (:metaclass ordered-class)
      (:slot-order x y))

    (defun distance (point)
      (sqrt (/ (+ (expt (standard-instance-access point 0) 2)
                  (expt (standard-instance-access point 1) 2))
               2.0)))

### Implementation dependent: only in CLISP

You cannot assume that the slot-location values start at 0. In class `point`, for example, `x` and `y` will be at slot locations 1 and 2, not 0 and 1.

In more realistic uses of this mechanism, the calls to the low-level instance structure accessors would not actually appear textually in the source program, but rather would be generated by a meta-level analysis program run during the process of compiling the source program.

### 29.10.2. Funcallable Instances

Instances of classes which are themselves instances of `CLOS:FUNCALLABLE-STANDARD-CLASS` or one of its subclasses are called funcallable instances. Funcallable instances can only be created by ``ALLOCATE-INSTANCE` (`CLOS:FUNCALLABLE-STANDARD-CLASS`)`.

Like standard instances, funcallable instances have slots with the normal behavior. They differ from standard instances in that they can be used as functions as well; that is, they can be passed to `FUNCALL` and `APPLY`, and they can be stored as the definition of a function name. Associated with each funcallable instance is the function which it runs when it is called. This function can be changed with `CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION`.

The following simple example shows the use of funcallable instances to create a simple, `DEFSTRUCT`-like facility. (Funcallable instances are useful when a program needs to construct and maintain a set of functions and information about those functions. They make it possible to maintain both as the same object rather than two separate objects linked, for example, by hash tables.)

    (defclass constructor ()
      ((name :initarg :name :accessor constructor-name)
       (fields :initarg :fields :accessor constructor-fields))
      (:metaclass funcallable-standard-class))
    ⇒ #>FUNCALLABLE-STANDARD-CLASS CONSTRUCTOR>
    (defmethod initialize-instance :after ((c constructor) &KEY)
      (with-slots (name fields) c
        (set-funcallable-instance-function
          c
          #'(lambda ()
              (let ((new (make-array (1+ (length fields)))))
                (setf (aref new 0) name)
                new)))))
    ⇒ #<STANDARD-METHOD :AFTER (#<FUNCALLABLE-STANDARD-CLASS CONSTRUCTOR>)>
    (setq c1 (make-instance 'constructor :name 'position :fields '(x y)))
    ⇒ #<CONSTRUCTOR #<UNBOUND>>
    (setq p1 (funcall c1))
    ⇒ #(POSITION NIL NIL)

### 29.10.3. Customization

#### 29.10.3.1. Function `CLOS:STANDARD-INSTANCE-ACCESS`

Syntax
  `(`CLOS:STANDARD-INSTANCE-ACCESS` `instance` `location`)`
Arguments
  `instance`
    an object
  `location`
    a slot location
Value
  an object
Purpose

  This function is called to provide direct access to a slot in an instance. By usurping the normal slot lookup protocol, this function is intended to provide highly optimized access to the slots associated with an instance.

  The following restrictions apply to the use of this function:

  - The `instance` argument must be a standard instance (it must have been returned by ``ALLOCATE-INSTANCE`(`STANDARD-CLASS`)`).
  - The `instance` argument cannot be an non-updated obsolete instance.
  - The `location` argument must be a location of one of the directly accessible slots of the instance's class.
  - The slot must be bound.

  The results are undefined if any of these restrictions are violated.

### Implementation dependent: only in CLISP

The second and third restrictions do not apply in CLISP. CLISP's implementation supports non-updated obsolete instances and also supports slots with allocation `:CLASS`.

#### 29.10.3.2. Function `CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS`

Syntax
  `(`CLOS:FUNCALLABLE-STANDARD-INSTANCE-ACCESS` `instance` `location`)`
Arguments
  `instance`
    an object
  `location`
    a slot location
Value
  an object
Purpose

  This function is called to provide direct access to a slot in an instance. By usurping the normal slot lookup protocol, this function is intended to provide highly optimized access to the slots associated with an instance.

  The following restrictions apply to the use of this function:

  - The `instance` argument must be a funcallable instance (it must have been returned by ``ALLOCATE-INSTANCE` (`CLOS:FUNCALLABLE-STANDARD-CLASS`)`).
  - The `instance` argument cannot be an non-updated obsolete instance.
  - The `location` argument must be a location of one of the directly accessible slots of the instance's class.
  - The slot must be bound.

  The results are undefined if any of these restrictions are violated.

### Implementation dependent: only in CLISP

The second and third restrictions do not apply in CLISP. CLISP's implementation supports non-updated obsolete instances and also supports slots with allocation `:CLASS`.

#### 29.10.3.3. Function `CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION`

Syntax
  `(`CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION` `funcallable-instance` `function`)`
Arguments
  `funcallable-instance`
    a funcallable instance (it must have been returned by ``ALLOCATE-INSTANCE` (`CLOS:FUNCALLABLE-STANDARD-CLASS`)`).
  `function`
    A function.
Values
  The values returned by this generic function is unspecified.
Purpose
  This function is called to set or to change the function of a funcallable instance. After `CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION` is called, any subsequent calls to `funcallable-instance` will run the new function.

#### 29.10.3.4. Generic Function `CLOS:SLOT-VALUE-USING-CLASS`

Syntax
  `(`CLOS:SLOT-VALUE-USING-CLASS` `class` `object` `slot`)`
Arguments
  `class`
    a class metaobject - the class of the `object` argument
  `object`
    an object
  `slot`
    an effective slot definition metaobject
Values
  an object
Purpose

  This generic function implements the behavior of the `SLOT-VALUE` function. It is called by `SLOT-VALUE` with the class of `object` as its first argument and the pertinent effective slot definition metaobject as its third argument.

  The generic function `CLOS:SLOT-VALUE-USING-CLASS` returns the value contained in the given slot of the given object. If the slot is unbound, `SLOT-UNBOUND` is called.

  The results are undefined if the `class` argument is not the class of the `object` argument, or if the `slot` argument does not appear among the set of effective slots associated with the `class` argument.

Methods

`(`CLOS:SLOT-VALUE-USING-CLASS` (`class` `STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`
`(`CLOS:SLOT-VALUE-USING-CLASS` (`class` `CLOS:FUNCALLABLE-STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`

  These methods implement the full behavior of this generic function for slots with allocation `:INSTANCE` and `:CLASS`. If the supplied slot has an allocation other than `:INSTANCE` or `:CLASS` an `ERROR` is `SIGNAL`ed.

  Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.

`(`CLOS:SLOT-VALUE-USING-CLASS` (`class` `BUILT-IN-CLASS`) `object` `slot`)`
  This method `SIGNAL`s an `ERROR`.

#### 29.10.3.5. Generic Function `(SETF CLOS:SLOT-VALUE-USING-CLASS)`

Syntax
  `(`(SETF CLOS:SLOT-VALUE-USING-CLASS)` `new-value` `class` `object` `slot`)`
Arguments
  `new-value`
    an object
  `class`
    a class metaobject - the class of the `object` argument.
  `object`
    an object
  `slot`
    an effective slot definition metaobject.
Value
  The `new-value` argument.
Purpose

  The generic function `(SETF CLOS:SLOT-VALUE-USING-CLASS)` implements the behavior of the `(`SETF` `SLOT-VALUE`)` function. It is called by `(`SETF` `SLOT-VALUE`)` with the class of `object` as its second argument and the pertinent effective slot definition metaobject as its fourth argument.

  The generic function `(SETF CLOS:SLOT-VALUE-USING-CLASS)` sets the value contained in the given slot of the given object to the given new value; any previous value is lost.

  The results are undefined if the `class` argument is not the class of the `object` argument, or if the `slot` argument does not appear among the set of effective slots associated with the `class` argument.

Methods

`(`(SETF CLOS:SLOT-VALUE-USING-CLASS)` `new-value` (`class` `STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`
`(`(SETF CLOS:SLOT-VALUE-USING-CLASS)` `new-value` (`class` `CLOS:FUNCALLABLE-STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`

  These methods implement the full behavior of this generic function for slots with allocation `:INSTANCE` and `:CLASS`. If the supplied slot has an allocation other than `:INSTANCE` or `:CLASS` an `ERROR` is `SIGNAL`ed.

  Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.

`(`(SETF CLOS:SLOT-VALUE-USING-CLASS)` `new-value` (`class` `BUILT-IN-CLASS`) `object` `slot`)`
  This method `SIGNAL`s an `ERROR`.

#### 29.10.3.6. Generic Function `CLOS:SLOT-BOUNDP-USING-CLASS`

Syntax
  `(`CLOS:SLOT-BOUNDP-USING-CLASS` `class` `object` `slot`)`
Arguments
  `class`
    a class metaobject - the class of the `object` argument.
  `object`
    an object
  `slot`
    an effective slot definition metaobject.
Value
  `BOOLEAN`
Purpose

  This generic function implements the behavior of the `SLOT-BOUNDP` function. It is called by `SLOT-BOUNDP` with the class of `object` as its first argument and the pertinent effective slot definition metaobject as its third argument.

  The generic function `CLOS:SLOT-BOUNDP-USING-CLASS` tests whether a specific slot in an instance is bound.

  The results are undefined if the `class` argument is not the class of the `object` argument, or if the `slot` argument does not appear among the set of effective slots associated with the `class` argument.

Methods

`(`CLOS:SLOT-BOUNDP-USING-CLASS` (`class` `STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`
`(`CLOS:SLOT-BOUNDP-USING-CLASS` (`class` `CLOS:FUNCALLABLE-STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`

  These methods implement the full behavior of this generic function for slots with allocation `:INSTANCE` and `:CLASS`. If the supplied slot has an allocation other than `:INSTANCE` or `:CLASS` an `ERROR` is `SIGNAL`ed.

  Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.

`(`CLOS:SLOT-BOUNDP-USING-CLASS` (`class` `BUILT-IN-CLASS`) `object` `slot`)`
  This method `SIGNAL`s an `ERROR`.

Remarks. In cases where the class metaobject class does not distinguish unbound slots, true should be returned.

#### 29.10.3.7. Generic Function `CLOS:SLOT-MAKUNBOUND-USING-CLASS`

Syntax
  `(`CLOS:SLOT-MAKUNBOUND-USING-CLASS` `class` `object` `slot`)`
Arguments
  `class`
    a class metaobject - the class of the `object` argument.
  `object`
    an object
  `slot`
    an effective slot definition metaobject.
Value
  The `object` argument.
Purpose

  This generic function implements the behavior of the `SLOT-MAKUNBOUND` function. It is called by `SLOT-MAKUNBOUND` with the class of `object` as its first argument and the pertinent effective slot definition metaobject as its third argument.

  The generic function `CLOS:SLOT-MAKUNBOUND-USING-CLASS` restores a slot in an object to its unbound state. The interpretation of “restoring a slot to its unbound state” depends on the class metaobject class.

  The results are undefined if the `class` argument is not the class of the `object` argument, or if the `slot` argument does not appear among the set of effective slots associated with the `class` argument.

Methods

`(`CLOS:SLOT-MAKUNBOUND-USING-CLASS` (`class` `STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`
`(`CLOS:SLOT-MAKUNBOUND-USING-CLASS` (`class` `CLOS:FUNCALLABLE-STANDARD-CLASS`) `object` (`slot` `CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION`))`

  These methods implement the full behavior of this generic function for slots with allocation `:INSTANCE` and `:CLASS`. If the supplied slot has an allocation other than `:INSTANCE` or `:CLASS` an `ERROR` is `SIGNAL`ed.

  Overriding these methods is permitted, but may require overriding other methods in the standard implementation of the slot access protocol.

`(`CLOS:SLOT-MAKUNBOUND-USING-CLASS` (`class` `BUILT-IN-CLASS`) `object` `slot`)`
  This method `SIGNAL`s an `ERROR`.

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
29.9. Method Combinations | Home | 29.11. Dependent Maintenance