View this PageEdit this PageLock this PageLinks to this PageUploads to this PageHistory of this PageHomeRecent ChangesSearchHelp Guide

Introduction

The basic idea in Self is "the power of simplicity". This dialect of Smalltalk has a smaller number of concepts that can be combined to give you all the power of more complex alternative and even more.

Self is a pure object oriented language with message passing at the bottom.

Let's look at these concepts one at a time.

"Object oriented" means that the system is built from entities called objects which are like little computers in that they can store information, manipulate it and exchange it with other objects. The system does not have a separation between data and programs, each of which is a weaker concept than a computer. An interesting thing about objects is that they have a very well defined interface, separating what is inside the object from what is outside.

"Pure" means that the system doesn't include anything that isn't an object. In contrast, hybrid languages such as C++ or Java have a set of primitive data types for low level operations. Self is more radical than most languages in this respect as explained in the next paragraph.

"Message passing at the bottom" means that not only does the object have to ask other objects to do things for it using what we call messages, but it must also do so when dealing with itself. One note about messages - given how most languages are implemented, a lot of people think this is just another term of "indirect subroutine call". This view is too limiting: it is better to think of messages as something like packets flowing on a network between two computers. Anyway, most languages only try to make an object look like an object on the outside. Once we are programming inside the object, we revert back to a data and program view. In Self an object looks exactly the same on the inside as it does on the outside and any code must send messages to "self" to get work done. Where in Smalltalk we would have
       myVar := myVar + 1
in Self this would be written as
      self myVar: self myVar + 1
(which happens to work in Smalltalk as well). It should be obvious how the language got its name. Fortunately the syntax allows us to omit all those "self" when they are implied by a lack of a valid receiver expression, so the above would normally be written as
       myVar: myVar + 1

Self is based on prototypes instead of classes.

In some object oriented programming languages, "classes" are just a compile time construction, while in others they are actual objects present at runtime. In the latter case, there are the following relations between objects:
  • IsA: each object is an instance of a given class. The format of the object's data and the code it understands are stored in the class.
  • Includes: an object "knows" about a set of other objects and uses them to get its work done. Some languages allow some of these objects to actually be embedded physically in the main object, but most just store pointers to them in the instance's data.
  • InheritsFrom: both objects involved must be classes. The subclass defines what data and programs it has in addition to those available in the superclass. In theory this is not needed since you could get the same effect by copying everything in the superclass into the subclass, but in practice this is very convenient when you have to change something since this automatically propagates to all subclasses.
Self makes all objects exactly alike by allowing each one to define its own data and programs in the form of a set of "slots" and merging the IsA and InheritsFrom relation into a single DelegatesTo one.

A slot has a name and a value. The object Includes all the objects pointed to by the values of its slots. When you send a message to an object, it finds the slot with that name and returns the associated value (or executes it, if it is a program, and returns the result). Some slots are tagged as "parent slots", and if a message is received that isn't the name of any local slot then the search is continued in these parent objects. We say that an object DelegatesTo its parents any message it doesn't implement itself. So an object both Includes its parents and DelegatesTo them.

It should be obvious how DelegatesTo is like InheritsFrom in that the first object acts like a subclass of the second. But it is also like IsA in that we can take a bunch of very similar objects and move all the common slots into a shared parent object. We call this their "traits" object (a term from very early Smalltalk tutorials)and they have some of the same functions as a class in other languages.

There are two things that classes do, but traits objects don't. The first is reflection: they allow us to manipulate the objects at a lower level than normal, which is something programming tools need to do. Self provides special "mirror objects" for this purpose. The second thing classes do is act as a factory for the creation of new instances. Fortunately, there is a more elegant way to create objects: simply make a copy of an existing one. So for every kind of object we want to create, we set aside an example of it called the "prototype". Note that there is nothing special about the prototype to the system - it is only in our minds that it is so.

Self is a living system.

Most programming languages are very like a blue print. In fact, Richard Stallman uses a recipe as an analogy in his arguments for free software. You write down some text and a compiler will generate a file that can be loaded into a computer to get the effect you want.

A living system is very different. If you were to send a copy of human DNA to some friendly aliens in the next galaxy, they would not be able to create a person from it. If you have DNA, then you just have DNA. But if you have DNA and a working cell then you can have as many cells as you want. Smalltalk is like that in that all the written code is just a part of the system. The only way you can shutdown the system and restart it is by storing every single bit in memory in an "image" file (called "snapshot" in Self). Only then can the drawings, windows, texts and other objects that were manually created by using the system itself be preserved.

For the first three versions of Self you had both alternatives. You could save a snapshot of your work, but this wasn't too important since Self programs were created with external text editors and loaded into an "empty world". In Self 4 the situation changed significantly since the tools were developed for programming within the system itself. You can still recreate the BareBones world entirely from the text sources but the Demo world can only be loaded as a snapshot.

Reflection

It was already mentioned that Self has mirror objects to allow the same kind of reflection that classes provide in other languages. It also has activation objects that allow the debugger to examine and change running programs. But most of the implementation, including the critical message passing mechanism, is hidden inside a black box created as a C++ program. The "R" in Self/R stands for reflection, meaning that the full system will be available by virtue of being entirely implemented in itself.