Archive for the 'Tutorial' Category

Blame it on Io! A slow-paced introduction to the Io language

Wednesday, March 15th, 2006

No posts in a week, I have been silent too long. Blame it on Io!

You see, Io is a contagious disease. It affects programmers’ brains. The incubation period is extremely short, due to the simplicity of its syntax. But the damages are extensive, particularly for Algol-derivative programmers: you will end up messed up! Huh… I forgot to mention the vectors include reading posts about Io. I just hope your infection will not be as bad as mine. (If I do not get google hits from E.R. fans with this paragraph, what will it take?)

Yo Io!

First things first, let’s get the token “Hello World!” implementation out of the way:

"Yo Io!" print

Aside from my poor taste in greeting phrases, you probably noticed how concise and simple this statement is. At first sight, to most programmers, it appears to be written backward. Not so if you think that the "Yo Io!" object — which happens to be a string — is being sent the message print. Everything in Io is an object, and I really mean everything: lists, files, strings, numbers and even messages!

Attack of the clones

Well that is not fully accurate, to be pedantic, I should have written: everything in Io is a prototype. Indeed, Io is a prototype-based language. C++/Java/C# programmers, here comes surprise #1: Io knows nothing about classes. In class-based languages, classes describes the structure and behaviour of objects in term of methods whereas instances hold the objects’ data. Prototype-based languages do not make this distinction. A prototype is both a class and an instance. To get a new instance, you clone an existing prototype. To get a new class you add or alter the behaviour of an existing prototype. Sounds complex? Let your inner mad scientist free:

Sheep := Object clone

In English, Sheep is defined as a clone of Object — the parent of all Io prototypes.

Sheep legCount := 4

In brain-damaged English, the legCount property of a Sheep is defined as four. Non-programmers would have you believe this is equivalent to: a sheep has four legs.

MutantSheep := Sheep clone

A MutantSheep is defined as a clone of a Sheep. No surprise here, we all knew that!

MutantSheep legCount = 7

But their legCount property is set to seven! Most inner mad scientists tend to go for six legs, but my inner mad scientist is also nonconformist. I explain the difference between = and := in the next section. Just pretend they are the same for the moment.

dolly := MutantSheep clone

Here be dolly the mutant sheep! The convention is to use an upper-case character at the beginning of the name of prototypes acting as classes and a lower-case character for prototypes acting as instances.

Lots of slots

Once again, I have to confess that I have been inaccurate: I wrote legCount was a property of a Sheep whereas, in Io speak, it is actually a slot of Sheep. A slot associates a value to a name within the context of a prototype. Sheep holds one slot named legCount with the value 4. Here comes surprise #2: slots can contain variables and methods.

Sheep baa := method("bah!" print)

The baa slot on Sheep is defined as a method which prints “bah!”. Simple, no?
You noticed earlier that Io has two different assignment operators: := and =. Both of them are actually methods on Object. := is actually parsed as setSlot and = is parsed as updateSlot. From the method names you probably inferred the difference: := creates a new slot on a prototype from a name and a value whereas = updates an existing slot with a new value.
Io interprets the previous code sample like this:

Sheep setSlot("baa", method("bah!" print))

There is madness to Io’s methods

In case you were wondering, method is a method on Object that creates anonymous methods. The self-referential aspect of what I just wrote surely enlightened you, not. Rewind. Slow motion. The method method takes a list of parameters. All but the last one are arguments to the created method. The last argument is the body of the method. In this example, I define the growMoreLegs slot on MutantSheep to be a method with one parameter:

MutantSheep growMoreLegs := method(n,
    legCount = legCount + n)

Apart from the slightly surprising syntax, I hope this all sounds pretty familiar so far. Things are about to change big time! Surprise #3: a method can control when and if to evaluate an argument. This lets us define flow control constructs (if, unless, while, etc.) as methods. Most of them already exist on Object of course. One construct is missing though and we will implement it here. But first, we will botch the job:

Object unless := method(cond, then, else,
    if(cond, else, then))

The problem: cond, then and else are evaluated when unless is called. We do not want that. What we want is: unless cond is true, evaluate then, otherwise evaluate else. In Io this is done like this:

Object unless := method(
    if(call eval argAt(0),
        call eval argAt(2),
        call eval argAt(1)))

Update: see jer’s comment for a better implementation
What looks like a nice trick, is actually extremely powerful. Lisp programmers laugh in the background, they’ve used it successfully since 1958! I will not explore this vast topic any further in this post — I must save some ammunition for future posts!
By the way, I hope you appreciated the fact that Io is a dynamic language: we just added a method to the Object prototype!

Lobby for Io!

Before concluding, I would like to point out that Sheep and MutantSheep are defined like slots. But what is the underlying prototype? In Io, this is the Lobby. So what? Well, Lobby ultimately derives from the Object prototype, like all other prototypes. But where do you think we found the Object prototype? Bingo! It is a slot in the Protos slot of Lobby. I suggest you read this again. You are not dreaming: Object is both a slot of a slot in the Lobby and an ancestor of the same Lobby. How is that for another self-referential bit of self-reference?

Time to conclude, I hope this introduction will entice you to dwell deeper into this really amazing language. Believe me, we have only scratched the surface!
For a more complete, formal and accurate presentation of Io, check out The Io Programming Language.
Visit the official website or join the posse on irc.freenode.net#io.

Advertisements