[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.6 GOLD: Graham’s Object Language Definition

This document:

The point of GOLD is that a non-trivial OO language can be defined in just a few dozen lines of LISP. For example, GOLD supports:

Amusingly, this help file is actually longer that the source code that implements GOLD.

Installation

GOLD is at least files:

Extensions

Examples

Subclassing

Something is a subclass of *object* with methods area,volume and instance variables $height.

(klass (*object*) area $height volume)

Note: in GOLD, everything has to be a subclass of *object*.

Creating a Global Class

(defparameter *body* (klass (*object*) area $height volume))

As a side-effect of the above call, set and get methods are defined for all the $variables. So, after that call, it is possible to call:

($height abody)
(setf ($height abody) 1)

Creating an Instance

Example:

(inst *body*)

Note: inst is defined in terms of a lower-level inst0 function:

(defun inst (parent)
  (let ((obj (inst0 parent)))
    (init  obj) 
    obj))

So, if you want to turn off auto-initialization, then use the lower-level command inst0.

Define a method

Methods are just like LISP functions, with at least one argument (the instance being processed).

(defmeth volume *body* (me)
         (* ($height me) (area me)))

Note: if you get this error:

Can't set #<FUNCTION (LAMBDA (U)) {10043C9DA9}> 
    of #1=#((#2=#((#3=#)
               #(INIT
                 WITH-ZLOTS
                 ZLOTS
                 AREA
...

then have called defmeth on a method name not listed in the call to klass that defined this class.

Defining an Initialization Method

(defmeth init *body* (me)         
         (setf ($height me) 1))

Note that such methods are optional. All sub-classes of *object* inherit a default, do nothing, initialization method.

Extending a Super-class Method

Methods in sub-classes can access method definitions in super-classes via the next function.

For example, suppose a *body* has a default init action which a sub-class called *tube* wants to access:

(defmeth init *body* (u)         
         (setf ($height u) 1))

(defmeth init *tube* (u)
         (next u)
         (setf ($radius u) 10))

Worked Example

Bodies have a default height of one and a volume equal to their area times their height. Tubes are a sub-class of bodies whose area is their radius times pi, squared. Tubes initialize themselves as an extension to body’s initialization.

(defparameter *body* (klass (*object*) area $height volume))
(defparameter *tube* (klass (*body*) $radius))

(defmeth init *body* (u)         
         (setf ($height u) 1))

(defmeth area *tube* (u)
         (* pi (expt ($radius u) 2)))

(defmeth volume *body* (u)
         (* ($height u) (area u)))

(defmeth init *tube* (u)
         (next u)
         (setf ($radius u) 10))

(defun !tube ()
  (let ((tub (inst *tube*)))
    (format t "~a~%" (volume tub))
    (with-zlots tub 
      #'(lambda (prop value) 
          (if (dollarp prop)
              (format t "~a = ~a~%" prop value))))))

Note the functions with-zlots and dollarp in the !tube function. The former loops through all slot names while the latter selects anything that starts with a $ sign. This function just prints out all the instance variables (skipping over the functions).

Hints

Functions that are generic to all objects can be written to *object* methods. For example:

(defmeth zlots *object* (self)
            (coerce (layout (parents self)) 'list))

(defmeth with-zlots *object* (self fn)
         (dolist (zlot (zlots self))
           (funcall fn zlot (lookup zlot self))))

Bugs

If *print-array* is non-nil, then display a class will lead to an infinite loop (since the first field contains a pointer back to itself, so a full print takes never terminates).

GOLD’s source code sets *print-array*. However, in some obscure debugging scenarios, this is not enough to stop the infinite loop. Therefore, if your code just hangs, restart LISP and make sure *print-array* is nil.

For More

See GOLD1 and 2; and GOLD3; and GOLD4.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated on April 19, 2011 using texi2html 5.0.