Most dynamic object-oriented programming languages in use today are slots-based. These include Python, PHP and Javascript.
The slots-based model is based on the idea that an object is a collection of selectors that map to members. The members are either references to other objects, or some kind of function object representing a method. When another object invokes a method, it does so by searching the selector map for a matching selector, then invokes the function (if any) that is retrieved from the map.
Some nice things about the slots-based model are:
Kew follows a different model: its objects are dispatcher-based. This paradigm used to be more common but seems to be on the wane (with some caveats you could argue that it is the paradigm employed by Smalltalk, for example).
In the dispatcher-based model, an object is a function that dispatches and executes method invocations. It is not possible for the caller to inspect the map from which this is done, nor to verify that a map is being used for dispatch. It is also not possible to modify the map (changing behaviour dynamically) or squirrel away a function for later invocation.
If the dispatch function can’t be modified by a caller (in Kew it can’t), a number of things are not possible:
It is not possible to reflect on the dispatch function as a first class object. Nor is it necessary, because it already is a first class object. If a caller wants to invoke a method then it can just go ahead and invoke it. It will be handled by the dispatch function somehow—perhaps by signalling an exception. To do otherwise is a violation of the “tell, don’t ask” principle and breaks encapsulation.
Common patterns of use such as creating proxies to forward invocations to remote objects do not require encapsulation to be broken; just send the message on and return any results or exceptions. The remote object will decide what it can handle.
Another common pattern is to reflect upon method selectors (e.g. JUnit invokes all methods whose names start with “test”). This is not necessarily a good pattern (an alternative is just to list out the things you want run), but it’s easy to achieve in Kew using Source of MyObject to return an object model of the source code (although this does not allow a malicious caller to obtain references to objects that break encapsulation, it can allow a caller to obtain secrets, such as a hard-coded password string, and so is subject to security checks in Kew).
It isn’t possible to pull out a function of an object to store and invoke it later, and again it isn’t necessary to do so. In a slots-based language it’s just as valid to create a simple object that encapsulates the object and method to be called and store and invoke that. It should be indistinguishable from the underlying method function and yet does not break encapsulation. I argue this is better design, because you should create new behaviours by creating new objects, not by taking objects to pieces (although many languages make this less convenient than just reaching in and grabbing the underlying method function).
So, to summarize, the slots-based object model isn’t really object-oriented because it’s centered on the methods of an object, not on the object itself. It allows callers to break encapsulation, and exposes them to implementation details.
Many people do use slots-based languages to program cleanly and effectively and it’s telling that you don’t see the kinds of activities described as “advantages” of the slots-based model happening much in most people’s code. While it can be seen as powerful, all the advantages can be gained in other, better ways, and the usual disadvantages of breaking encapsulation avoided.
Comments
Slots in Self
Hi Duncan,
You should have a look at the Self programming language, if you haven’t already. Read the 1987 OOPSLA paper titled Self the Power of Simplicity by Dave Ungar and Randall Smith, see http://research.sun.com/self/papers/self-power.html
I don’t know too much about it but have read a couple of papers on Self a while ago. Self uses slots etc. James Noble made us read some papers on Self when I was doing Honours.
It was also nice to meet you at XTC back in early November.
Enjoy the read.
Cheers Craig
re: Slots in Self
Hi Craig,
it was good to meet you too. Yes, I know Self reasonably well (though I wouldn’t describe myself as an expert) and I know the Ungar and Smith paper.
Self is an interesting and well designed language which has pairs of methods acting as setter/getter pairs for slots. There’s a mismatch between the description of slots in Ungar and Smith’s paper and how I describe them. I say a slot is a stateful named thing belonging to an object and supporting two operations: read the current slot contents and set the current slot contents to a new value. The paper’s authors describe each of what I call an operation as a slot. Leaving aside the terminology differences, I think that Self can be seen as an example of (in my terms) a slots-based language. From Ungar and Smith’s abstract: “Slots unite variables and procedures into a single construct.” It is precisely this that I argue isn’t really very object-oriented.
Historically, Self was one of the strongest influences on the design of Kew. I like the fact that they really made an effort to reduce the number of concepts one has to be concerned with. I feel that in Kew I’ve been able to take that idea further by removing statefulness as a language primitive and moving it into the library of standard objects. In Kew, objects are only behaviour, nothing else.
thanks, I may look at Kew
thanks, I may look at Kew once I have my MSc completed … not to far away.
Cheers Craig