Io is a prototype based, object-oriented language developed by Steve Dekorte. I would describe Io as minimalist, it has very little syntax and no reserved words; even the control structures are expressions with messages being sent to objects. It aims to be consistent in its syntax and forms as well as to conceptually unify common language features under powerful abstractions.
Day 1 wasn't too involved and this may be thanks to Io's clean, minimal syntax (an interview with Steve Dekorte in the book indicates that some people have said they would prefer a bit more syntax to make it easier to read). There really is not much syntactic sugar, the only example I came across is that operators like + and - do not need parentheses when receiving their parameters (operators are simply method calls, this is also true for control structures like if and while).
There weren't too many exercises in day one so among other things I went ahead and coded up some (4) implementations of the Fibonacci series. The code can be seen here. I'll discuss some it below. My coding style is not necessarily idiomatic Io, i just did what made it most readable to me.
This is what making objects looks like in Io, although there are no classes, Io does create a type property (or slot in Io speak) for objects whose name starts with an uppercase letter, the value of the type slot is the name of the object. So “Rect type” produces “Rect”. The type field seems like something useful for separating class like things from object like things (see preconceptions). slotNames is a method that gives a list of all slots defined on the object it is sent to (i.e. a list of messages that you can send to that object - excluding messages defined by ancestors). Note that message passing/method calling does not have the dot syntax present in many OO langs, a space separates the message from the receiving object.
The method call (also a method btw - not a keyword) is how we create new methods to assign to slots (in this case a slot named fib), the receiving object in this case is the global Object. The last argument to this method is the method body, while all others are the parameters that the method you are defining receives.
Io has three assignment operators, =, := and ::=. A simple = will do the typical assignment only if the slot specified on the left already exists. := will create a slot (if it doesn’t exist already) and assign a value to it. ::= will create the slot, assign the value and also create a setter method for that slot. I find the distinction between the first two to be quite nice, since scope is used in Io quite a bit, it is a handy way to make sure you are not creating new slots when you don’t want to.
We also see the syntax for if’s in io. Like any method call, the method name is followed by parenthesis and the argument list, in this case: the condition, the expression to execute when it is true and the expression to execute when it is false; all separated by commas. Being a purely object-oriented language, if is not a free function, it is a slot (property) on the ‘Object’ object that is created for you in the global scope. Note: there is an if syntax that takes ‘then’ and ‘else’ parts. It looks like this
if(y < 10) then(x := y) else(x := 2)
Take a minute to parse that and see if you can separate the messages being passed from the parameters those messages take.
The above is an implementation of Fibonacci with memoization (i.e. keeping previously calculated results in memory for quick reuse). It shows use of a Map data structure as well as my attempt to create a closure like thing (so that one can call the method without needing to see the store for the previously calculated results). I’m not sure if I have done this in the best way, line 9 is needed when I assign this method to a slot on another object. I’m not sure if there is a way around that, but I haven’t really gotten to the discussion of scopes (or closures) in Io yet.
UPDATE: The proper way to do this is in this post.
This code also shows that since methods are objects themselves they also have slots to which you can attach helper methods (fibhelp in this case). I find that pretty neat.
Want some context? Checkout the first post.