Table of Contents

Smalltalk

We all know the story of how Steve Jobs back in the days went to visit Xeroc PARC, and then ran home and built the Macintosh - an insanely great thing. What he saw at PARC was a computer with windows, with a mouse, with drawing capability; the Smalltalk computer.

Since then, Smalltalk has had its share of dedicated followers and - seemingly as important - has been a source of inspiration for every object oriented programming language since. When Steve Jobs went to start NeXT, the Objective C language was born, borrowing as much as practically possible from Smalltalk. Java was inspired by both Objective C and Smalltalk. Ruby's creator, Matz, was inspired by Smalltalk, and Smalltalk served as the inspiration for Perl 6's object model design.

And still, most of us have never even tried it.

Enter Squeak

I've spent the last few weeks getting aquainted with Squeak - an open source Smalltalk implementation, and I'm totally blown away by what it has to offer. The first obstacle you'll meet is that Squeak is really different from any programming environment you've ever used. The programming language itself is really dead simple, but the environment is different. First of all, Squeak is more like an operating system than a programming language. When working in Squeak, you'll be working on an image - which is a snapshot of code, state and graphical elements. Your classes and objects don't live in files, like you're used to, but rather as objects inside this image. You won't be able to immediately start using any old text editor to edit your code, but instead you'll be using things like the Object Browser. Don't let this put you down, I guarantee you'll find it's worth it!

object_browser.jpg

Where are my classes?

As as example, imagine a trivial Ruby application with a couple of classes. Usually, each of these classes are defined inside a file - but you can still extend them in other places, usually by some kind of meta programming technique. As a consequence, the exact definition of a class is somewhat hard to find except at runtime. Depending on what files are loaded and what commands are issued, your classes will change behaviour - one of the main reasons nobody as yet has been able to build things like refactoring support into a Ruby IDE; while you're programming it's practically impossible for your programming environment to know the current state of any object; be it a class, module or any other object.

In Smalltalk, however, there really isn't a distinction between runtime and programming time. If for instance you discover a bug in your application code at runtime, you can bring up the debugger and locate the bug. Then, inside the debugger, you can fix the bug, accept the change and resume operation. And from that point on, the bug is no longer inside your application; you changed the class definition in the debugger, and it's immediately fixed wherever the class is referenced.

If Smalltalk had files defining the classes, and then loaded these files at startup, this wouldn't be possible. For me this demonstrates that classes are actually more Object-like in Smalltalk than in say Ruby. Just like you can change the data in your objects, you can change the behaviour of your code without rebooting the entire system.

One of the hardest things to grasp was how to create a class in Squeak. Since there are no files defining classes and no class keyword to define classes I couldn't quite figure out how to create a class. As it turns out, the way to create a class is to send a message to another class:

Object subclass: #NameOfSubclass
      instanceVariableNames: ''
      classVariableNames: ''
      poolDictionaries: ''
      category: 'AST-Tokens'

So by sending this message a new subclass (Person in this example) will be created and immediately available all over. And where can you interact with your newly created class? Anywhere, really. You can open up a Workspace (like a text editor window) and type Smalltalk code into it. Select the text and click Cmd-d (to do it), Cmd-p (to print it), Cmd-i (to inspect it). Or you can use the Browser and work with your classes there. It takes a little getting used to, but after a while it feels like the most natural way to interact with your classes.

Methods have history

Another advantage with an image based system is that state is preserved for you. If you open a Workspace and define a variable, you can save your image, forget all about it for months and return to find your variable still available in memory. Compare that to an IRB session, where everything goes away before you can type Ctrl-d.

Know what? The methods in your classes are objects too, they even have history. If you create a Person class and give it a meet:at: method you can use to introduce a Person instance to other Person instances at a place and then change your mind about the implementation, you just might regret it at some time. Which is the reason any professional uses source control management to track changes in his source code. In Squeak, the objects track changes in methods for you, so you need not worry if you forgot to commit a change before you changed something. Just pop up your Browser, select the Person class and the meet:at: method. Click the Versions button, and Squeak will give you something like this:

message_versions.jpg

Here you can see that we changed the method comment, and Squeak lets us revert to an earlier version of our method implementation should we change our minds.

No dots

A minor detail: Ruby, like a lot of programming languages, uses the dot (.) to separate an object from a method in a method call (Smalltalkers would refer to this as receivers and messages). So, strictly speaking, the way of adding two numbers in Ruby is:

1.+(2)

However, this is so ugly that people would probably not accept it. So Matz added what is referred to as syntactic sugar which lets you say:

1 + 2

You can skip the dot, skip the parentheses and even put in a space to make it look like a mathemathical operation. The ugly truth, however, is that it's a hack.

In Smalltalk a receiver (the object that receives a message) is separated from its message by one or more spaces:

1 + 2

This is a so-called unary message, and this is the formal way of sending it. Smalltalk also has keyword messages, which again are simulated in Ruby by using hashes:

person.name = 'John', :address => 'Milky way'

What this really boils down to, however, is this:

person.name=('John', {:address => 'Milky way'})

Not that pretty, is it? In Smalltalk, this kind of messages are called keyword messages, and are called as such:

person.name:'John' address:'Milky way'

And the message is defined as and referred to as Person»name:address: . Ruby 1.9 mimicks this behaviour, but not quite.

A really clean object model

One of the first things any newcomer to Ruby falls in love with is the fact that even the most primitive things are pure objects. Whenever you show off Ruby, typing stuff like 1.day.ago into an IRB session, any java guy will be impressed that you can call methods on the object 1; that it's really an object. Well, Smalltalk takes it further. I already mentioned that classes are created by sending messages to a Class object, how about looping in Ruby? You'd do something like

while my_bottle.contains_beer?
  drink_some_more
end

So what does this while thing mean? Is it a method? Well, no. It turns out it's one of Ruby's keywords - along with unless, until, yield, when, in and others. A keyword is like a method without a receiver, as you'll have noticed if you ever tried to give your class a and method for example. This is Ruby's way of telling you that OO is OK in most cases, except:… Just like Java tells you objects are okay except for really rare stuff like Strings, numbers and the like. Smalltalk, on the other hand, has only 5 keywords: self, super, true, false and nil. And they're not even keywords but pseudo variables, but we'll leave it at that.

So the way to do a while loop in Smalltalk is obviously to send a message to some kind of object. In this case, the object in question would be a code block, and the message would be whileTrue.

[myBottle containsBeer] whileTrue: [drinkSomeMore]

The stuff inside the square brackets are Smalltalk blocks, so this example has a first block which evaluates to either true or false; which is sent the message whileTrue: with a block to be executed while the first block evaluates to true. The same goes for if/else; you send the ifTrue: / ifFalse: message to something that evaluates to either true or false along with a block to execute.

How long does it take to get my head around this stuff?

As I mentioned, it does take some effort to grasp the notion of an image based system. I downloaded the Squeak by example guide to Smalltalk, and read it on my way to work every day. It took me three days (two hours reading) to start liking Squeak, another three days to start understanding it, and that's where I am right now. I think I'm even more inspired by Squeak and Smalltalk than I was about Ruby when I started reading the Pickaxe six years ago. Unlike the situation when I started learning Ruby, there is a very attractive web framework for Smalltalk, so if you're doing web development, you really need to look into Smalltalk.

The thing I'm finding it hard to accept, however, is that this thing has been around for more than 25 years; and people are still programming like they did in the seventies. I just don't get it.