Welcome to Day 23 of this year’s A Language a Day Advent Calendar. Today’s topic is introduction to the Io programming language.
Facts about the language
- Prototype-based, object oriented
- Dynamically typed
- A homoiconic language
- Appeared in 2002
- Website: iolanguage.com
Installing and running Io
To install Io, download one of the packages for your operating system.
To run a program, run
$ io helloworld.io
Here is the minimum Hello, World! program in Io:
"Hello, World!\n" print
Alternatively, you can use
println to add the newline instead of
"Hello, World!" println
What happens in the Hello, World! program is you send the
To create a variable, use the
name := "John" ("Hello, " .. name .. "!") println
.. for string concatenation here.
There are also
= 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.
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
Io implements the prototype-based object-oriented mechanism. To create a new object or a type, clone the
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
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
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)
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.
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)
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.