Programming in Inform 7

Inform 7 is a programming language designed for the development of old-school parser-based adventure games, similar to those developed by Infocom in the 1980s, most famously Zork. It was developed in the mid-2000s as a replacement for Inform 6, which had much the same purpose but was less interesting for the purposes of this blog post, being a fairly standard C-like imperative programming language.

Inform 7 is not a standard C-like imperative programming language. Here is an example of a correct, executable program:1

"The Lady and the Tiger"

The lady is on top of the tiger.
The tiger is in a room.
"This lady hails from Niger
Niamey, I presume."

The lady wears a smile.
Her arm is in a sling.
Riding is an action
applying to one thing.

"The lady on the tiger
Up and down they sped."
After the lady rides the tiger
Now it wears the smile instead.

This code compiles into a small game with one room, a tiger, and a lady on top of that tiger. Each of these things has various states and attributes also defined in the poem, not least of which are their textual descriptions in quotation marks.

A careful reading of the code reveals how many operations in Inform 7 correspond to more conventional languages. This code:

The lady is on top of the tiger.
The tiger is in a room.

means something like this:

lady =
tiger =
room =

tiger.location = room
tiger.rider = lady


After the lady rides the tiger
Now it wears the smile instead.

means something like:

if tiger.rider == lady

But beyond merely providing a verbose/seemingly non-technical way to express simple statements like these (in the vein of esolangs like SPL or Chef), Inform 7 uses its idiom for things that can be expressed very elegantly in natural language. Take the following lines:

A man can be happy or sad.

This statement assigns a new boolean property (happy or sad) to a class of things (men) in a way that’s much more succinct and semantically pleasant than a bunch of variables that can only true/false and the plumbing to give them appropriate relationships (man.happy = false etc). After defining these things, you can test and assert them with constructs like:2

At 00:00:
    if all men are sad,
      now all doors are closed.

No loops required!

Inform 7’s main constructs are rules and relations – rather than being object-oriented, it’s rule-oriented. This is eminently sensible for a language designed to construct complex interactions centred around a turn-based parser interface. For every command issued by the player – EXAMINE WINDOW, GO NORTH, TAKE BREATH, ASK LADY ABOUT TIGER – the author can define a number of rules to be evaluated before, during and after this command is issued. These rules may check conditions (only take photographs if the player is carrying a camera), perform convenience actions (unlock doors the player has the key to) and, of course, define the outcome of a given action, as in the tiger poem.

After the lady rides the tiger:
    now it wears the smile instead.

This rule definition relies on our earlier definition of the verb “riding”.

Riding is an action applying to one thing.

We can define any number of arbitrary actions that the player and non-player characters can do, with various conditions such as how many objects it applies to and whether it requires light, and then we can attach rules to it in order to define what must happen before, after and during its execution.3

Check riding:
    if the player is wearing spurs,
          say "That would be animal cruelty." instead.

Relations allow us to test conditions and to assert states. By writing The tiger is in the room, we are stating a relation between the tiger and the room that we can later test.

if the tiger is in the room,
	say "There is a tiger here."

So far so standard. But Inform’s natural language syntax gives us a very elegant way of testing historical conditions as well.

if the tiger was in the room,
	say "A tiger has been here. You can tell by the orange hair in the carpet."

In case you didn’t notice, the only change I made between the first block and second block of code was to substitute was for is. A tense change, trivial in spoken language, would be quite an undertaking in a traditional programming language – even if you had already designed mechanisms for recording history, expressing if the tiger was in the room would likely not be such a brief, elegant line of code.

The interplay between properties, rules and relations can be used to model complex systems, using code that reads like a rather pendantic textbook. Here’s a simple example from the manual, defining weight:

A length is a kind of value. 10m specifies a length. An area is a kind of value. 10 sq m specifies an area. A length times a length specifies an area.

A weight is a kind of value. 10kg specifies a weight. Everything has a weight.

The verb to weigh means the weight property. A thing usually weighs 1kg.

Definition: A thing is light if its weight is 3kg or less.

Definition: A thing is heavy if its weight is 10kg or more.

Inform’s code most reminds me of the sort of writing mathematicians use in proofs. This comes as no surprise, as the language’s author, Graham Nelson, is a mathematician. Here’s the Fibonacci sequence in Inform 7, taken from §10.11 of the Inform Recipe Book:

To decide what list of numbers is the first (F - a number) terms of the Fibonacci sequence:
    let the Fibonacci sequence be {1, 1};
    let N be 3;
    while N < F:
        let the last term be entry (N - 1) of the Fibonacci sequence;
        let the penultimate term be entry (N - 2) of the Fibonacci sequence;
        let the next term be the last term plus the penultimate term;
        add the next term to the Fibonacci sequence;
        increment N;
    decide on the Fibonacci sequence.

The main downside I’ve found to the natural language approach is that, with Inform 7 being such an expressive language, it’s easy to forget it’s still a programming language and try to just write what you want to achieve in plain English. This generates a compiler error, just like any other programming language, and you remember you’re writing code in a very particular, precisely structured subset of natural English.

Although I have fairly limited interest in writing parser-driven interactive fiction, I love playing with Inform 7 and figuring out how to model different things in it, just because it’s fun and different from other languages. As TRG Green says in this article about the language, “Some things are so beautifully made and so intriguing that we want to use them just for their own sake.”

  1. I was originally going to use this poem, but it sadly doesn’t compile on modern versions of Inform 7. ↩︎

  2. The colons and indentation are optional, which is great for code poems. ↩︎

  3. A check rule happens just before an action is executed. You can also define a before rule, which happens before the check. ↩︎

similar posts