next up previous
Next: 2. Messages and Delegation Up: No Title Previous: No Title

1. The Object Simulation

Consider the problem of simulating the activity of a few interacting agents wandering around a simple world of rooms and corridors. Real people are very complicated; we do not know enough to simulate their behavior in any detail. But for some purposes (for example, to make an adventure game) we may simplify and abstract this behavior.

Let's start with the simplest stuff first. We'll define some basic classes of objects, using the simple object system described in lecture on March 19. The objects in our computational world all have names. An object will give you a method to find out its name if you send it the name message. We can make a named object using the procedure make-named-object. A named object is a procedure that takes a message and returns the method that will do the job you want.gif For example, if we call the method obtained from a named object by the message name we will get the object's name.

(define (make-named-object name)
  (lambda (message)
    (case message
      ((NAMED-OBJECT?) (lambda (self) #T))
      ((NAME) (lambda (self) name))
      ((SAY)
       (lambda (self list-of-stuff)
         (if (not (null? list-of-stuff))
             (display-message list-of-stuff))
         'NUF-SAID))
      ((INSTALL) (lambda (self) 'INSTALLED))
      (else (no-method)))))

(define foo (make-named-object 'george))

((foo 'name) foo) ==> george

The first formal parameter of every method is self. The corresponding argument must be the object that needs the job done. This was explained in lecture, and we will see it again below.

A named object has a method for four different messages. It will give a method that confirms that it is indeed a named-object; it will give a method to return its name; it will give a method for the message say that will print out some stuff; and it will give a method for installation that does nothing.

A place is another kind of computational object. A place has has a neighbor-map of exits to neighboring places, and it has things that are located at the place. Notice that it is implemented as a message acceptor that intercepts some messages. If it cannot handle a particular message itself, it passes the message along to a private, internal named-object that it has made for itself to deal with such messages. Thus, we may think of a place as a kind of named-object except that it also handles the messages that are special to places. This kind of arrangement is described in various ways in object-oriented jargon, e.g., ``the place class inherits from the named-object class,'' or ``place is a subclass of named-object,'' or named-object is a superclass of place.''

(define (make-place name . characteristics)
  (let ((neighbor-map    '())
        (things       '())
        (named-obj (make-named-object name)))
    (lambda (message)
      (case message
        ((PLACE?) (lambda (self) #T))
        ((THINGS) (lambda (self) things))
        ((CHARACTERISTICS) (lambda (self) characteristics))
        ((NEIGHBOR-MAP)
         (lambda (self) neighbor-map))
        
        ...other message handlers...

        (else     ; Pass the unhandled message on.
         (get-method message named-obj))))))

Where:

(define (get-method message object)
  (object message))


next up previous
Next: 2. Messages and Delegation Up: No Title Previous: No Title

Hal Abelson
Wed Mar 11 23:54:42 EST 1998