Io is an amazing language. It’s powerful, yet simple. Minimalism is its core principle. And not so far and dark if you’re a Ruby coder, believe me.

Contrary to Ruby, Io doesn’t have any magic statement like if , while , class , def , etc. Everything is a method call, everything is open. if, while and the like are all implemented using the full power of Io in only a few lines of code.

Oh, and Io uses space instead of dots to separate the receiver from the method ( receiver method instead of receiver.method ), just like in English. You’ll get used to it…

Method, I Has It and Nice They Are

Io is a prototype-based language like Javascript. Creating methods in Io is indeed a bit like in Javascript, you assign a method to a slot.

uSmell := method ( what , "no you smell " .. what ) uSmell ( "fish" ) # => no you smell fish

See that the first argument of method is the argument of the method uSmell .

But wait! How does Io knows that the first argument of method is an argument and not a method call or local variable? What? Wait! What? Hein?

Lazy Eval aka Super Disco Nuclear Powers with Rubber Handles

See, if you don’t supply arguments, Io doesn’t really know that your method handle arguments. But all is not lost, you still can take full control and evaluate the arguments yourself, in the context of your choice, how you what, in your own very special way!

nameIt := method ( call argAt ( 0 ) name ) nameIt ( x ) # => "x"

You get the call method whenever you’re inside a method, that holds all the information about the current method call: the arguments, the sender, etc. So, call argAt(0) name retrieve the name of the first message sent as the first argument.

This is how all control flow methods are implemented in Io. Here’s if :

if := method ( call evalArgAt ( 0 ) ifTrue ( call evalArgAt ( 1 )) ifFalse ( call evalArgAt ( 2 )) )

And here’s how you could implement Ruby’s Fixnum#times :

Number times := method ( varName := call argAt ( 0 ) name i := 0 while ( i < self , call sender setSlot ( varName , i ) # assign the index var call evalArgAt ( 1 ) # evaluate the block i = i + 1 ) ) 3 times ( i , i println ) # 2 # 1 # 0

Boom!

Magic!

But still, remember …