Ioke
A homoiconic, prototype-based experiment for the JVM and CLR from JRuby core developer Ola Bini that put expressiveness above everything else - including performance - and folded Io, Smalltalk, Lisp, and Ruby into one radically flexible message-passing language.
Created by Ola Bini, a Swedish developer and JRuby core team member then working at ThoughtWorks, who built Ioke as a deliberate experiment in how expressive a language could be made
Ioke (file extension .ik) is what happens when a language designer deliberately refuses to compromise. Announced by Ola Bini on November 6, 2008, it is a dynamic, strongly typed, prototype-based language for the Java Virtual Machine - later also the Common Language Runtime - “designed to be as expressive as possible,” in Ola Bini’s own description, with everything else, performance included, subordinate to that goal. It folded together the prototype model of Io and Self, the message-passing purity of Smalltalk, the macros and condition system of Lisp, and the readable surface of Ruby, and it wore its experimental status proudly: the official site warned plainly that Ioke “is not production ready.”
History and origins
Ola Bini came to Ioke from the engine room of the polyglot JVM movement. A Swedish developer at ThoughtWorks and a core contributor to JRuby - the Ruby implementation for the JVM - he had spent years inside other people’s language implementations and wanted to explore a question of his own: if you designed a language for expressiveness first, with no concessions to performance or convention, what would it look like?
The answer arrived quickly. Announced in November 2008, the first release - playfully named Ioke 0 - shipped on December 23, 2008, as ikj, an implementation written in Java. Subsequent major releases were named with letters rather than numbers: Ioke S (January 23, 2009) was the first with several active contributors, adding syntactic macros, full regular expressions, for comprehensions, and aspects; the Ioke E cycle (April 2009) brought ikc, a C# implementation for the CLR, making Ioke a two-runtime language; and Ioke P (December 23, 2009 - exactly one year after Ioke 0) landed as ikj 0.4.0 and ikc 0.4.0 with tuples, structs, destructuring assignment, message rewriting, sequences, and a rebuilt parser. It would prove to be the final major release.
Design philosophy: expressiveness first
Every official description of Ioke led with the same priority - the language’s own site declared expressiveness “the ultimate goal.” Bini designed the language to be its own most important tool - an instance of language-oriented programming in which the base language is mostly a substrate for building the abstractions, and even the domain-specific languages, that a problem actually calls for.
The mechanics serve that goal everywhere:
- Everything is a message. Like Smalltalk and Io, all computation - arithmetic, control flow, assignment - is the sending of messages to objects.
if,while, and even=are not keywords but messages, which means user code can define constructs that are indistinguishable from built-ins. - Prototypes, not classes. There are no classes. New objects are made by mimicking existing ones (Ioke’s word for cloning), and an object’s “kind” is just the chain of things it mimics, in the tradition of Self and Io.
- Homoiconicity. Code is data: a program is a chain of message objects that can be inspected, transformed, and rewritten at runtime. On this foundation Ioke built unusually powerful macro facilities - including syntactic and destructuring macros - in a language whose surface looks nothing like Lisp.
- A condition system, not exceptions. Borrowed from Common Lisp, Ioke’s error handling separates signaling a condition from deciding how to recover: handlers can invoke restarts established deeper in the call stack, so errors can be repaired where they occurred instead of unwinding the world. Bini reportedly counted it among the language’s more successful decisions.
- Aspects and hooks. Cross-cutting behavior can be attached to existing objects and messages, rounding out an unusually complete toolkit for bending the language to the program.
What Ioke looks like
Hello World is a single message sent to a piece of text:
"Hello, world!" println
This bank-account sketch, adapted from the examples shipped with the language, shows prototypes and mimicking in action - note that Account is itself a usable object, not an abstract class:
Account = Origin mimic do(
balance = 0.0
deposit = method(v, self balance += v)
show = method("Account balance: $#{balance}" println)
)
Account deposit(10.0)
Account show
And this generator, adapted from the Fibonacci example in the distribution’s examples folder, displays destructuring assignment and closures (fn) - a generator built from a lexical closure over two cells:
generativeFib = method(
(curr, succ) = (0, 1)
fn(
(old, curr) = (curr, succ)
succ += old
old
)
)
fib = generativeFib
"First ten: #{(0..9) map(n, fib call)}" println
The distribution’s examples folder leaned into the language’s malleability, including versions of an account program with all its messages localized into Chinese, Danish, Dutch, and other natural languages - a party trick, but a pointed one: in a language where nothing is a keyword, even the vocabulary is yours to redefine.
Evolution and tooling
For a two-year experiment, Ioke was strikingly complete. It was developed test-first, and the distribution included ISpec, an RSpec-style behavior-driven testing framework written in Ioke itself (with stubbing and mocking from Ioke P onward); DokGen, a documentation generator combining docs with executable specs; and IIk, an interactive REPL. Java integration connected Ioke programs to the JVM ecosystem, and the parallel ikc implementation extended the same language to .NET. The code was MIT-licensed, hosted on Sun’s Kenai forge and on GitHub, where the surviving repository dates from February 2010.
The experiment wound down almost as quickly as it wound up. In July 2010 Bini preannounced Seph, a successor designed to keep Ioke’s core ideas - prototypes, homoiconicity, expressiveness - while being “pragmatic enough for real world usage,” with acceptable performance as a starting point, along with immutable objects and a concurrency focus. Ioke P remained the last release; the final changes reached the repository in mid-2011.
Current relevance
Ioke is dormant, and has been for well over a decade. There is no package ecosystem, no maintained distribution, and no community activity to speak of; the website, wiki, and source repository survive as a well-preserved archive. Running it today means building the MIT-licensed source from GitHub against a period JVM - an afternoon of code archaeology rather than a deployment decision, exactly as its “not production ready” warning always implied.
Why it matters
Ioke never sought users, and by that measure it can’t be said to have failed - it was, in Bini’s own framing, an experiment in all senses of the word, run in public with releases, documentation, and tests.
It mapped the far end of the expressiveness axis. Most languages trade expressiveness against performance, familiarity, and tooling. Ioke set every one of those dials to zero to find out what maximum flexibility actually feels like - message-passing everything, malleable syntax, macros in a non-Lisp - and published the results.
It revived ideas mainstream languages had shelved. A working Common Lisp-style condition system with restarts, prototype-based objects, and true homoiconicity, all running on the era’s two dominant enterprise runtimes, gave a generation of JVM and .NET programmers a hands-on encounter with paradigms their day jobs had abstracted away.
It fed its successors. Seph was built directly on Ioke’s lessons, and the language stands as one of the clearest documented cases of a designer using one language as the research prototype for the next - the experiment written up not as a paper, but as a codebase.
Timeline
Notable Uses & Legacy
Seph programming language
Ioke's most concrete legacy: Ola Bini's 2010 follow-up language Seph was explicitly designed to take the concepts pioneered in Ioke - prototype-based objects, a strict homoiconic model - and refine them into something with acceptable performance for real-world use, adding immutable objects and a focus on concurrency
ISpec and DokGen (self-hosted tooling)
Ioke was designed to be "its own most important tool": the distribution included ISpec, an RSpec-style behavior-driven testing framework written in Ioke (gaining stubbing and mocking in Ioke P), and DokGen, a documentation generator that combined documentation with executable specs - and the language itself was developed test-first with them
Language-oriented programming research
Ioke served as a public laboratory for language-oriented programming and DSL construction on the JVM and CLR, demonstrating how far homoiconicity, syntactic macros, and a Common Lisp-style condition system could be pushed inside a Ruby-flavored syntax - work Bini discussed in venues like Software Engineering Radio episode 154
The polyglot JVM wave
Alongside Clojure and early Scala adoption, Ioke was one of the visible experiments of the 2008-2010 alternative-JVM-language moment, showing that the JVM could host semantics radically unlike Java's - prototype-based dispatch, macros, restarts - and its examples folder localized a sample program into several natural languages to stress its malleable syntax