The Io Programming Language

The Sales Pitch

Io describes itself as minimal object-oriented programming language with a small C runtime. It's design is influenced by languages such as Self, Lua, Smalltalk, NewtonScript, Act1, and LISP. It represents all code as a "tree of messages" similar to Lisp with all code being represented in a tree of s-expressions.

Everything is Objects

All values in Io are objects which recieve messages. This includes messages themselves. All objects in Io are constructed by cloning another existant object. This is the hallmark of prototype-based programming.

Sheep := Object clone
Sheep texture := "woolie"
Sheep speak := method("baaaaah" println)
ands := list(Sheep clone, Sheep clone, Sheep clone)
and foreach(speak)

Everything is based around passing messages including assignements. Operations such as x := 10 are transformed into setSlot("x", 10). Messages are first dispatched to the target object. If the target object does not handle the message, it tries each prototype the object inherits from. Objects can inherent from multiple prototypes by adding objects to the protos list.

Sheep := Object clone
Sheep bleat := method("baahh!" println)

Raven := Object clone
Raven caw := method("caw!" println)

Lizard := Object clone
Lizard hiss := method("hissss." println)

andNull := Sheep clone appendProto(Raven) appendProto(Lizard)
andNull bleat // ===> baahh!
andNull caw   // ===> caw!
andNull hiss  // ===> hissss.

Classes

While prototypes provide fluidity, it can be nice to to constract "class" prototype. Something that acts as a reliable anchor point for when it's time to start defining out the your application. Io provides this through init. init is a message the is sent to an object during its cloning process. This allows you to setup internal state of a new instance.

Shelf := Object clone do (
    init := method(
        self items := list()
    )
    
    addItem := method(item, items push(item) ; self)
)

upperShelf := Shelf clone 
lowerShelf := Shelf clone

upperShelf addItem("shiny rock") addItem("old radio")
lowerShelf addItem("cool rock") addItem("nice book")

The Lobby

Io has "no" globals. However, in practice, Io gives you access to it's root object: the Lobby. The Lobby is the default, top-level reciever. This object serves as the contain for global values in Io. Like all other objects in the language, it can be inspected.

Io> Lobby
==>  Object_0x55c65af02990:
  Lobby            = Object_0x55c65af02990
  Protos           = Object_0x55c65af02840
  _                = Object_0x55c65af02990
  exit             = method(...)
  forward          = method(...)
  set_             = method(...)

Code as a Tree of Messages

In Io, all code is stored as a tree of messages. This tree gets passed to objects for them to handle execution of. Since messages are objects, they can be inspected and modified at runtime. This modification forms the basis of Io's metaprogramming abilities. For a silly example, here's a method that takes in a message and increments every number in it by one:

incrementExpression := method(m,
    cachedResult := m cachedResult
    if(cachedResult type == "Number",
        newValue := cachedResult + 1
        m setCachedResult(newValue) \
            setName((newValue) asString)
    ,
        m arguments foreach(subm, incrementExpression(subm))
    ) 
    if(m next, incrementExpression(m next))
)

m := method(1 + 2 * 3 * 4 + 5)

writeln(getSlot("m") message, " = ", m) 
    // ==> 1 +(2 *(3) *(4)) +(5) = 30
incrementExpression(getSlot("m") message)
writeln(getSlot("m") message, " = ", m)
    // ==> 2 +(3 *(4) *(5)) +(6) = 68

Many of Io's built-in functionality leverage this powerful reflection to operate. Examples of building up more complex custom syntax float about online.

For those familiar with Modal, the idea of passing around trees of messages may sound familiar. Perhapse there is a link between this and rewriting.

TicTacToe in Io

I always feel like implementing a game is a good way to feel out a language. A simply game to make is TicTacToe. The following is that program implemented in Io.

(show raw)