0. Intended Use
SELF is an object-oriented language intended for exploratory programming.
1. Basic Concepts
SELF is a dynamically-typed object-oriented language. Like Smalltalk,SELF has no type declarations. Also like Smalltalk, SELF provides blocks(lexically-scoped function objects related to closures) as a basic construct.Standard control structures for iteration and Boolean selection, as wellas programmer-defined control structures, are constructed out of theseblocks. However, unlike Smalltalk and many other object-oriented languages,SELF has no classes. Instead it is based on the use of prototypes.In this approach, new objects are created by cloning (shallow-copying)existing objects (the prototypes). The state of the new objects can thenbe set to instance-specific values. Each object conceptually defines itsown object-specific behavior, and may borrow behavior from other objects(called parents) using delegation (instance-level inheritance). Also unlikeSmalltalk, a SELF object accesses its state entirely by sending messagesrather than using special syntax for accessing a variable or changing itsvalue. This results in many messages sent to "self", hence thename of the language. [US87, CUL89]
2. Objects
SELF objects consist of named slots, each of which contains areference to some other object. Some slots may be designated as parentslots by appending asterisks to their names (objects may have multipleparents, thus supporting multiple inheritance) [CUL89]. Objects may alsohave SELF code associated with them by having slots contain referencesto method objects containing the code.
When a message is sent to an object (called the receiver of themessage), the object is searched for a slot with the same name as the message.If a matching slot is not found, the contents of the object's parent slotsare searched recursively, using built-in multiple inheritance rules todisambiguate any duplicate matching slots. [This search is similar to thatwhich takes place in a class-based system during dispatching, except thatin SELF the objects being searched are instances representing applicationentities, rather than class objects representing descriptions of otherobjects.] Once a matching slot is found, its contents are evaluated andthe result is returned as the result of the message send. An object accessesits own state (slots) by sending messages to "self" (the receiverof the current message).
A non-code object evaluates to itself (and so the slot holding it actslike a variable). A method object is a prototype activation record. Whenevaluated, the method object clones itself, fills in its selfslot with the receiver of the original message, fills in its argument slots(if any) with the arguments of the message, and executes its code. Theself slot is a parentslot so that the cloned activation record inherits from the receiver ofthe original message. [US87]
SELF supports assignment to data slots by associating an assignmentslot with each assignable data slot. The assignment slot contains theassignment primitive object (effectively a method). When the assignmentprimitive is evaluated as the result of a message send, it stores its argumentinto the associated data slot. A data slot with no corresponding assignmentslot is a constant or read-only slot, since a running program cannot changeits value. For example, most parent slots are constant slots. However,a parent slot can be made assignable by defining a corresponding assignmentslot. An assignable parent slot permits an object's inheritance to be changeddynamically. [CUL89] See entry under 2.6 state.
2.1 operations
Operations are defined for objects by including slots containing methodobjects, as described under 2. Objects. To invoke operations, messagesare sent to designated receiver objects; hence SELF supports a "classical"object model.
2.2 requests
See entry under 2. Objects.
2.3 messages
See entry under 2. Objects.
2.4 specification of behavioral semantics
Behavior in SELF is defined by specifying the corresponding methods.There are no types or classes in SELF, and therefore no separate specificationsof operation signatures or other descriptive information about behavior.
2.5 methods
See entries under 2. Objects, and 2.1 operations.
2.6 state
In SELF, objects consist of named slots used to represent both statevariables and operations. Objects access variables in the same way theyinvoke operations: by sending messages. For example, to access its Xvariable, a point object sends itself the "X"message. The message finds the slot named "X",and evaluates the object found there. If the Xvalue is a number, the result of the evaluation would be the number itself.To change the value of its X variable, a pointobject sends itself the "X:" messagewith the new value as its argument. The message finds the slot named "X:"(which is the assignment slot corresponding to X),and evaluates the object found there (which would be the assignment primitive,as described in the SELF entry under 2. Objects).
2.7 object lifetime
To make a new object in SELF, an existing object (called the prototype)is cloned (shallow-copied). The slots in the new object that correspondto state variables (including parent slots) can then be set to instance-specificvalues. An addition, the structure of the new object can be changed byadding or deleting slots, using special language primitives. As in Smalltalk,objects exist as long as there are references to them from other objects(SELF supports garbage collection).
2.8 behavior/state grouping
SELF supports a "classical" object model.
2.9 communication model
3. Binding
SELF is a dynamically-typed language, and provides for run-time bindingof a message sent to an object to the method that implements the requestedoperation. SELF provides a form of classical object model in which thebinding choice is based on the receiving object itself (rather than itsclass, since SELF has no classes). See entry under 2. Objects.
4. Polymorphism
SELF supports the form of polymorphism provided by run-time bindingof a message sent to an object to the method that implements the requestedoperation. Since SELF is classless, the method that implements a givenoperation can potentially differ for each object (instance) thatdefines that operation, rather than just for each class. See entry under3. Binding.
5. Encapsulation
SELF as described in [US87] does not provide encapsulation, in the senseof having separate public and private interfaces. Any object can send amessage referencing any named slot, including assignment slots, containedwithin any other object. This sort of encapsulation could be provided throughsome technique for achieving the effect of private slots [probably withminimal impact on other key aspects of the language]. SELF, however, doesnot distinguish between accessing state and accessing behavior, and thusconceals this implementation issue from users.
6. Identity, Equality, Copy
Each SELF object has a unique identity which provides a means to referto the object independent of its state or behavior. SELF represents objectreferences using direct tagged pointers, rather than indirectly throughan object table. Cloning (shallow-copying) produces a new object with adistinct identity from its prototype.
7. Types and Classes
Like Smalltalk, SELF has no type declarations. Checking that a messagesent to a given object can be handled by that object (or by objects itdelegates to) is performed at run-time.
SELF also has no classes. Since SELF uses prototypes rather than classes,each object conceptually defines its own format, behavior, and inheritance(rather than having a separate class object to define this). A naive implementationof this approach would require that each object explicitly implement bothits own class-like format, method, and inheritance information, and itsown instance-like state information. However, SELF uses an implementationtechnique that allows it to regain much of the storage efficiency of sharedclass information. This is possible because few SELF objects have totallyunique format and behavior. Instead, almost all objects are created bycloning some other object and then modifying the values of the assignableslots. Major changes in the format or inheritance of an object can onlybe accomplished by invoking special primitives. A prototype and the objectscloned from it, identical except for the values of their assignable slots,are called a clone family. In the SELF implementation, objects arerepresented by the values of their assignable slots, if any, and a pointer(not visible to the user) to a structure called the object's map;this map is shared by all members of the same clone family. Maps are immutableso that they may be shared by objects in the same clone family. However,when the user changes the format of an object or the value of one of anobject's constant slots, the map no longer applies to the object. In thiscase, a new map is created for the changed object, starting a new clonefamily. The old map still applies to any other members of the originalclone family.
From the implementation point of view, maps look much like classes,and achieve the same sorts of space savings for shared data. However, mapsare not visible at the SELF language level, but are instead consideredpart of the language implementation [CUL89]. This allows the user to seea model in which each object defines its own format, methods, etc., whileat the same time permits the elimination of redundancy where this is possible.Users may also create user-visible objects which serve as shared behaviorrepositories (and to which other objects can delegate to obtain sharedbehavior). These objects are called traits objects. The creationof traits objects is independent from the existence of maps; the user neednot create traits objects, while the implementation automatically generatesmaps.
8. Inheritance and Delegation
SELF supports implicit delegation [CMC92]. This means that whenan object cannot answer a message, the interpreter automatically delegatesit to another object (as opposed to explicit delegation, in whichdelegation is specified explicitly for each message to be delegated). InSELF, the object to which an object delegates a message is called the object'sparent. Objects have parent slots to inform the interpreter to whichobjects messages should be delegated.
9. Noteworthy Objects
9.1 relationships
9.2 attributes
9.3 literals
9.4 containment
9.5 aggregates
SELF supports two special aggregates: object arrays and byte arrays.Arrays contain only a single parent slot pointing to the parent objectfor that kind of array, but contain a variable number of element objects.Byte arrays differ from object arrays in supporting a special compact storageformat.
9.6 other
A method object is a prototype activation record. When evaluated,the method object clones itself, fills in its selfslot with the receiver of the original message, fills in its argument slots(if any) with the arguments of the message, and executes its code. Theself slot is a parentslot so that the cloned activation record inherits from the receiver ofthe original message. [US87]
SELF allows programmers to define their own control structures usingblocks. A block contains a method in a slot named value;this method is special in that when it is invoked (by sending valueto the block), the method runs as a child of its lexically enclosing activationrecord. The self slotis not re-bound when invoking a block method, but instead is inheritedfrom the lexically enclosing method. Block methods may be terminated witha non-local return expression, which returns a value not to thecaller of the block method, but to the caller of the lexically-enclosingnon-block method, much like a return statement in C. [CUL89]
10. Extensibility
10.1 Dynamic
SELF provides primitives for dynamically adding and deleting slots (andthus operations and variables) from objects, and for dynamically changingparents (and thus inheritance).
10.2 Metaclasses/Metaobject Protocol
Some of the basic behavior defined for all objects (e.g., how to cloneand how to print) is defined in explicit objects to which other objectsdelegate messages to obtain this behavior. As a result, it is possibleto imagine creating new versions of these basic objects, with variantsof these sorts of basic behavior. It is possible that such things as theprocess of delegation, or how message sends are handled, could themselvesbe defined in explicit objects and hence be changeable. However, it isnot clear from the references whether this is actually possible in SELF.
10.3 Introspection
SELF has no type or class objects. It might be possible to infer descriptioninformation from access to instances, but it is not clear from the referenceswhether this can be done in SELF.
11. Object Languages
12. Semantics of Base Classes (+ type constructors)
13. Background and References
[US87] and [CUL89] are basic references on SELF. [CMC92] describes thedesign variants found in prototype-based languages in general, includingSELF, and discusses the semantic differences between object models basedon classes and those based on prototypes. .
[CMC92] Christophe Dony, Jacques Malenfant, and Pierre Cointe, "Prototype-BasedLanguages: From a New Taxonomy to Constructive Proposals and Their Validation",in A. Paepcke, ed., OOPSLA '92 Conference Proceedings, ACM, Oct.,1992, published as SIGPLAN Notices, 27(10), Oct., 1992.
[CUL89] Craig Chambers, David Ungar, and Elgin Lee, "An EfficientImplementation of SELF, a Dynamically-Typed Object-Oriented Language Basedon Prototypes", in N. Meyrowitz, ed., OOPSLA '89 Conference Proceedings,ACM, Oct., 1989, published as SIGPLAN Notices, 24(10), Oct., 1989.
[US87] D. Ungar and R. B. Smith, "Self: The Power of Simplicity",in N. Meyrowitz, ed., OOPSLA '87 Conference Proceedings, ACM, Oct.,1987, published as SIGPLAN Notices, 22(12), Dec., 1987.