Thursday, September 13, 2007

smalltalk: philosophy, metaphor, semantics, syntax

Programming languages can be categorized in a number of ways: imperative, applicative, logic-based, problem-oriented, etc. But they all seem to be either an "agglutination of features" or a "crystallization of style." COBOL, PL/1, Ada, etc., belong to the first kind; LISP, APL-- and Smalltalk--are the second kind. It is probably not an accident that the agglutinative languages all seem to have been instigated by committees, and the crystallization languages by a single person.

Smalltalk's design--and existence--is due to the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioral building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages. Philosophically, Smalltalk's objects have much in common with the monads of Leibniz and the notions of 20th century physics and biology. Its way of making objects is quite Platonic in that some of them act as idealisations of concepts--Ideas--from which manifestations can be created. That the Ideas are themselves manifestations (of the Idea-Idea) and that the Idea-Idea is a-kind-of Manifestation-Idea--which is a-kind-of itself, so that the system is completely self-describing-- would have been appreciated by Plato as an extremely practical joke ...

I recalled the monads of Leibniz, the "dividing nature at its joints" discourse of Plato, and other attempts to parse complexity. Of course, philosophy is about opinion and engineering is about deeds, with science the happy medium somewhere in between. It is not too much of an exaggeration to say that most of my ideas from then on took their roots from Simula--but not as an attempt to improve it. It was the promise of an entirely new way to structure computations that took my fancy. As it turned out, it would take quite a few years to understand how to use the insights and to devise efficient mechanisms to execute them.
- alan kay, the early history of smalltalk
Most books on programming that I have seen don't include much in the way of philosophy or metaphor. They seem to be filled with detailed definitions and techniques.

But from the alan kay quote above it's clear that Smalltalk, the first OOPs language drew heavily from philosophical principles - the monads of Leibniz, "dividing nature at its joints" from Plato. And that this approach leads to a more elegant and internally consistent programming language ("crystallization of style"), rather than a mix of human memory intensive bits and pieces ("agglutination of features")

Maybe we would be better off today if philosophy and also the use of metaphor was taught side by side with programming?

<message receiver><message>
<receiver object><message>
<message receiver><message selector (optional message arguments>

Messages trigger methods in receiving objects

The above is the basic structure of smalltalk semantics. This initially appears easy to follow but for me it became confusing at the level of specific examples

100 + 200

In this case 100 is a message receiver, + is a message selector (binary type) and 200 is an argument for +

Both 100 and 200 are SmallInteger class instances

I found two things difficult to understand (counter intuitive) about this example:
1) Why was + being called a selector, ie. what was it selecting?
2) The 100 and 200 which are similar types of things are behaving in different ways in the example. The 100 is a message receiver and the 200 is an argument to the + message selector

This sort of thing frustrates me because in the end I'm reduced to rote learning through not really understanding the underlying meaning of the way in which smalltalk was designed. Now thanks to help from some experts I have an explanation.

The metaphors that work here are:
An object (which has various properties) receives a message which tweaks one of those properties

Or a language metaphor:
The subject (which comes first) is directed by the different parts of the rest of the sentence (verbs, etc.)

Message selectors (such as +) are called selectors because they select properties from the receiving object. As an object myself, I can visualise and personalise this quite easily. If someone comes to me and delivers a message then the particularity of the message switches on (selects) certain parts of my mind, ie. accesses particular properties of my mind

I don't really need to know the details of the SmallInteger class to appreciate this, just that the + message selector will trigger something inside that will enable it to complete the task of adding +200 to 100

Another thing that confused me was finding the right metaphor to explain this particular thing. Another smalltalk metaphor is the biological cell, that the contents of the cell are protected or encapsulated and that they respond to messages from outside.

This metaphor is great for helping to understand encapsulation and complexity - cells can diversify and combine to create complex organisms. But it didn't help me explain why + was called a message selector. However, the object and language metaphors did help here. So you need to know the right metaphors for the particular task at hand.

I'll round this out a bit more by using some other examples, mainly from Stephane Ducasse's book, Squeak: Learn Programming with Robots

There are 3 types of messages - unary, binary and keyword

Unary: pica east
"pica" (robot object) is the message receiver. "east" is the message selector. It's just like someone approach me and says, "turn east" That selects the part of my mind that thinks about directions.

Binary: 100 + 200
Already discussed

Keyword: pica go: 100
"pica" (robot object) is the message receiver. go: is a keyword message selectors, they accept arguments (100). So the message go: 100 is sent to the robot.

Keyword with multiple arguments:
pica polygon: numberOfSides size: sizeValue
"pica" (robot object) is the message receiver. The method or message selector is the double barreled polygon:size: (counter intuitive initially). The arguments are numberOfSides and sizeValue

Another Keyword with multiple arguments:
33 between: 30 and: 50
33 is the message receiver. The method or message selector is the double barreled between:and: The message arguments are 30 and 50

Ducasse, Stephane. Squeak: Learn Programming with Robots (2005) amazon, bots inc

The Monadology by Gottfried Wilhelm Liebniz

The Problem of Universals(philosophical essay)
"Plato was clearly a Realist about universals. His most famous metaphor for the reality of universals was to say that real universals "cut nature at its joints" (Phaedrus 265d-266a). He compares the task of definition to the job of being a butcher. The clumsy butcher just hacks things up in any old way, but the expert butcher deftly slices the animal at its natural joints, neatly separating naturally distinct segments of the animal."

1 comment:

Mithro said...

From reading your post I get the following feeling, a selector is basically "what you are asking to be done". The name feels like a misnomer to me, the selector is the 'type' of the message you are sending.

For example, in the "100 + 200" case, '+' is a selector because it is saying "could you please add".

This also works in the more advanced case, "33 between: 30 and: 50". The selector is 'between:and:' because you are asking "are you between x and y?".

Is that helpful at all?

I also feel that the double barrel syntax looses some of the calarity found in a normal computer languages. This is because what is being asked is split over two places. The 'and' doesn't really add any new information.

In a normal language like Python you might find something like, "33.between(30, 50)".

This can be seen in the "pica polygon: numberOfSides size: sizeValue" example which as you mentioned is clearly counter intuitive. In python this could be something like, "pica.drawPolygon(numberOfSides=10, size=2)". Which to me looks like what it would be, asking the pica object to draw a polygon with 10 sides and a size of 2.