Io at a Glance — A Language a Day, Advent Calendar 2019 Day 23/24

Welcome to Day 23 of this year’s A Language a Day Advent Calendar. Today’s topic is introduction to the Io programming language.

Welcome to Day 23 of this year’s A Language a Day Advent Calendar. Today’s topic is introduction to the Io programming language.

• Prototype-based, object oriented
• Dynamically typed
• A homoiconic language
• Appeared in 2002
• Website: iolanguage.com

Installing and running Io

To run a program, run `io`:

`\$ io helloworld.io`

Hello, World!

Here is the minimum Hello, World! program in Io:

`"Hello, World!\n" print`

Alternatively, you can use `println` to add the newline instead of `\n`:

`"Hello, World!" println`

What happens in the Hello, World! program is you send the `print` message to the string. In essence, this is a keystone knowledge of the design of Io.

Variables

To create a variable, use the `:=` assignment.

```name := "John"
("Hello, " .. name .. "!") println```

Notice the `..` for string concatenation here.

There are also `::=` and `=` forms, please refer to the Io guide for more details about them. `::=` also creates a setter, while `=` raises exception when the slot does not exist.

Functions

To create a function, use `method`. Let us first create a function that takes no arguments.

```greet := method("Hello, World!" println)
greet```

In the second line, you call the earlier created function.

Now, let us add an argument by just listing it before the function body:

```greet := method(name, ("Hello, " .. name .. "!") println)
greet("Alla")```

A Factorial example

Here is a possible solution of computing a factorial:

```factorial := method(n, if(n < 2, 1, n * factorial(n - 1)))

factorial(1) println # 1
factorial(5) println # 120
factorial(7) println # 5040```

But there is a simple way, as the function that we need is already built in:

```1 factorial println // 1
5 factorial println // 120
7 factorial println // 5040```

Objects

Io implements the prototype-based object-oriented mechanism. To create a new object or a type, clone the `Object` object:

`Person := Object clone`

An identifier that begins with a capital letter is considered a type. Otherwise, it is an object.

Object fields, or, slots, are accessed by sending messages to the object. For example, let us state that a `Person` works in the `X` company:

`Person company := "X"`

Now, we can create (or clone) people working in this company, and set their own slots:

```john := Person clone
john name := "John"
john age := 23

alla := Person clone
alla name := "Alla"
alla age := 22```

Whenever you need to access data, do it in the same manner:

```((alla name) .. " is " .. (alla age)) println
("She works in " .. (alla company)) println```

This program prints:

```Alla is 22
She works in X```

Be careful not to accidentally send messages that has no effect. This can happen when you omit a punctuation or type extra characters.

`("Works in" (alla company)) println 42`

The output of this line of code is a single string `"Works in"`.

Inheritance

Expressing inheritance is very easy, just clone a type and set the needed slots:

```Person := Object clone

XPerson := Person clone
XPerson company := "X"

YPerson := Person clone
YPerson company := "Y"```

Now, we have a type for people working in X and another type for those who work in Y.

```john := YPerson clone

alla := XPerson clone```

A Polymorphic example

Let us define the two types that are based on the `Animal` type. Just for diversity, let us add an unknown animal to the collection. That animal will be served but the `info` slot of the `Animal` type object.

```Animal := Object clone
Animal info := "I am an unknown animal"

Cat := Animal clone
Cat info := "I am a cat"

Dog := Animal clone
Dog info := "I am a dog"

zoo := list(Cat clone, Cat clone, Dog clone, Dog clone, Animal clone)
zoo foreach(i, x, x info println)```

In the foreach loop, the `x` variable loops over the `zoo` list items and it receives the `info` message, which returns a different string depending on a real type of the object.

As an exercise, modify the program to make `info` methods, for example:

`Dog info := method("I am a dog" println)`

Concurrency

Io offers support for coroutines and the scheduler, actors (which are objects having their own coroutine), and futures.

Let us use actors to implement the Sleep sort algorithm.

Sleep Sort

The main idea behind the following solution is to send an asynchronous message to an object. So, we define the `Sorter` type that has the `sort` method. To send the message (`sort` in our case) asynchronously, prefix it with `@@`.

```data := list(10, 4, 2, 6, 2, 7, 1, 3)

Sorter := Object clone
Sorter sort := method(n,
wait(n/10);
n println
)

sort_me := method(n,
s := Sorter clone;
s @@sort(n)
)

data foreach(n, sort_me(n))

wait(2)```

Get more

Io is a very syntactically compact language. Its basics can be learned literary within minutes. To dive deeper, examine its documentation pages:

The source codes of this issue of the series are located on GitHub.

Next: Day 24. Factor