Tiger
Tiger is the small imperative language Andrew W. Appel invented for his Modern Compiler Implementation textbooks: an Algol-family language with heap-allocated records, nested functions and an ML-flavoured expression syntax, designed not to be programmed in but to be compiled - by students. Nobody ships software in Tiger; many thousands of students have written a compiler for it.
Created by Andrew W. Appel, professor of computer science at Princeton University, who designed Tiger as the target of the student compiler project in his textbook series Modern Compiler Implementation (1997-1998). The C edition of the book was written with Maia Ginsburg. Neither the book nor the site explains the name; the tiger is Princeton's mascot, and the books - whose covers carry a tiger - are universally known as "the Tiger book"
Tiger is a programming language that nobody programs in. It has no compiler you can install, no standard library beyond eleven functions, no package manager, no users, no releases and no maintainer. It has never been used to ship a product, and it was never meant to be. What it has, instead, is nearly thirty years of people writing compilers for it — in ML, in C, in Java, in OCaml, in Haskell, in Rust — because Tiger is the language Andrew Appel designed to be the object of a compiler course.
Its whole specification is ten pages long. That is the design.
Where it came from
By the mid-1990s the standard undergraduate compiler project had a problem. Real languages were too big to compile in a semester, and the toy languages that fit in a semester were too small to teach anything: if the source language has no records, there is nothing to say about heap allocation; if it has no nested functions, there is nothing to say about static links and activation records; if it has one type, there is no type checker to write.
Andrew W. Appel, a professor at Princeton whose day job included the Standard ML of New Jersey compiler, wrote a textbook around a language sized precisely for that gap. Cambridge University Press published preliminary editions in 1997 — Modern Compiler Implementation in Java: Basic Techniques, and the same book with the interfaces rewritten in C and in ML — and the full editions in 1998, the C volume co-written with Maia Ginsburg. The language is defined in Appendix A, the “Tiger Language Reference Manual”, pages 512 to 521 of the ML edition. Appel’s own one-line description of it, still on his book site, is “a simple Algol-like language with heap-allocated records that is easily extensible to be functional, object-oriented, or both.”
The books have a tiger on the cover and are universally called “the Tiger book”. Neither the book nor the site explains the name; Princeton’s mascot is a tiger, which is the obvious inference and the one everybody makes, but Appel does not appear ever to have said so in print.
What the language is
A Tiger program is a single expression. That one decision shapes everything else: if, while, for, assignment, sequencing and declaration blocks are all expressions, some of which happen to produce no value.
let
var N := 8
type intArray = array of int
var row := intArray [ N ] of 0
var col := intArray [ N ] of 0
function printboard() =
(for i := 0 to N-1
do (for j := 0 to N-1
do print(if col[i]=j then " O" else " .");
print("\n"));
print("\n"))
in
printboard()
end
That is a fragment of queens.tig, the eight-queens solver Appel ships with the book among its sample programs, and it is the program every reader of the Tiger book has stared at. The syntax is ML’s — let ... in ... end, := for assignment, = for equality and for binding a function body — over semantics that are Pascal’s. Akim Demaille’s summary is hard to improve on: “a small yet very complete subset of Pascal dressed in a clean ML-like syntax.”
The type system is deliberately minimal and deliberately not trivial:
| Feature | Tiger |
|---|---|
| Predefined types | int, string — and nothing else; no floats, no booleans |
| Constructed types | records (named, typed fields) and arrays, both heap-allocated |
| Type identity | by declaration, not structure: two records with identical fields are different types |
| Recursion | mutually recursive types allowed in a declaration sequence, if every cycle passes through a record or array |
| Truth | zero is false, everything else is true; & and ` |
| Equality | = and <> on any two values of the same type; records and arrays compare by reference |
| Functions | nested, lexically scoped, mutually recursive within a declaration sequence, arguments by value |
| Memory | assumed garbage-collected; nil belongs to record types |
The standard library is eleven functions — print, printi, flush, getchar, ord, chr, size, substring, concat, not, exit — which is exactly enough to write test programs and not one function more.
Each of those choices buys a chapter of the book. Nested functions with free variables force static links and a real discussion of activation records. Heap-allocated records force garbage collection. Records-by-declaration force a symbol table with proper scoping and a type checker that cannot be faked with string comparison. Strings force a runtime. And the two syntactic forms id [ exp ] of exp (array creation) and id [ exp ] (array access) force an LALR(1) conflict that cannot be resolved by peeking one token ahead — an ambiguity in the grammar that course lecture notes have been explaining ever since.
The two lives of Tiger
The first life is Appel’s own. The book’s spine is a twelve-chapter pipeline — lexer, parser, abstract syntax, type checker, activation records, translation to IR trees, canonicalisation, instruction selection, liveness analysis, graph-colouring register allocation, and “putting it all together” — with skeleton modules provided per chapter in whichever of the three implementation languages the reader’s edition uses. The output is assembly for a real machine — the book works through MIPS and Sparc — typically run under the SPIM simulator. That structure is why Tiger compilers look alike across nearly three decades of student repositories: they are all the same twelve chapters.
Appel eventually stepped away from it. The second edition of the Java book, written with Jens Palsberg and published on 21 October 2002, swapped the project language for MiniJava, a subset of Java — the appendix in that edition is the “MiniJava Language Reference Manual” — on the reasonable grounds that students already know Java and can use ordinary Java tooling. The ML and C editions kept Tiger and stayed in print, so the language did not so much die as get left behind by one of its three siblings.
The second life is EPITA’s, and it is the more remarkable one. Around 2000 the French engineering school EPITA went looking for a project long enough and hard enough to make undergraduates confront specifications, documentation, testing, version control and nine months of team work, and picked compiler construction — explicitly, in Akim Demaille’s words, “for reasons not related to compiler construction”. Tiger was chosen because Appel’s book was the right size and because Tiger is rich enough that you do not have to invent a still-smaller language to compile into it.
What resulted is probably the largest deployment of Tiger in history: approximately 250 students a year, in groups of four, delivering around a dozen partial compilers each across a six-to-nine-month calendar. By the 2008 account that is “more than 2000 (proto-)compilers to assess each year”, which is a grading problem before it is a teaching problem. The project therefore grew a toolchain of its own, most of it released as free software:
tc, the reference compiler in C++, maintained by the teaching staff and distributed to students stage by stage as code with gaps.- Havm, an interpreter for Appel’s
Treeintermediate language, so that a student can execute and test the middle of a compiler rather than waiting until the assembly comes out at the far end. The 2008 paper notes, fairly, that “no industrial strength compiler exercises IRs this way”. - Nolimips, a MIPS simulator with an arbitrary number of general-purpose registers — so instruction selection can be tested before register allocation exists — and, conversely, the ability to reduce the register count so that spills can actually be provoked without writing pathological test programs.
- Monoburg, the Mono project’s BURG-style instruction-selector generator, extended with C++ output, named arguments and modules.
- A set of contributions back to GNU Bison aimed at learners: a fuller textual presentation of the LALR(1) automaton including item sets and lookaheads, graphical automaton output, named symbols in actions instead of
$1/$3, automatic location tracking, and the%destructordirective for reclaiming semantic values during error recovery.
EPITA also has its own dialect. Its “Tiger Compiler Reference Manual” changes the string escapes, the end-of-line handling and other details, and warns students to implement “the version of the language specified below, not that of the book” — the closest thing Tiger has to a competing standard.
A third strand runs alongside both: Tiger in Stratego, built at Utrecht University as the showcase application for the Stratego/XT program-transformation system, where every phase of the compiler is a set of rewrite rules that can be composed and recomposed at will. Version 1.2 dates from January 2003. It is the only Tiger compiler that exists to make a point about compilers rather than about students.
What Tiger is not
Language catalogues consistently file Tiger as a 1990s scripting language, which is wrong in an instructive way. There is no Tiger interpreter shell, no host application to embed it in, no dynamic evaluation, no dynamic typing and no library to speak of. It is a statically typed, compiled, Algol-family language whose reference implementations emit MIPS assembly. The misfiling is traceable: Tiger reached the catalogues through 99 Bottles of Beer, where Laurent Le Brun submitted a recursive Tiger version on 12 June 2005 — correctly annotated “Tiger’s language as described by Andrew Appel in his Modern Compiler Implementation books”, with a link to EPITA’s project site — and a second version arrived in 2012 from a Haverford College student taking CS350. A catalogue that inherits an entry without the annotation has nothing to classify it by but the name.
The “dormant” label is likewise half right. The language is not merely dormant but frozen: the 1998 appendix is the specification, there has never been a version 2, and there is no body that could issue one. The practice is very much alive. Public repositories implementing Appel’s Tiger, in a dozen host languages, were still receiving commits in August 2026.
Why it matters
Tiger is a rare example of a language whose value is entirely instrumental and entirely real. It has no users in the ordinary sense, and it has taught an enormous number of people the shape of a compiler: that the front end and the back end meet at an intermediate representation; that instruction selection and register allocation are separable problems; that static links are the price of nested functions; that a garbage collector is part of a language, not an add-on to it.
It also demonstrates something about how languages spread. Tiger never had a website, a foundation, a conference or a release. It travelled entirely inside a textbook, and then propagated by being assigned — first at Princeton, then at Columbia, at EPITA, at Haverford and at an unknown number of other institutions, and finally in the self-directed way people work through a famous book in public on a code-hosting site. Its lifetime distribution channel was a syllabus.
For the archaeologist there is one more lesson in it. Tiger is exactly as large as it needs to be to make the interesting problems appear and no larger, and that discipline is why it outlived its own author’s interest in it. Appel replaced it with MiniJava in 2002; nearly a quarter-century later people are still writing Tiger compilers, because ten pages of specification with a type checker, a heap and nested scope in them is still the cheapest way to learn how a compiler is put together.
Timeline
Notable Uses & Legacy
Modern Compiler Implementation (Appel, 1997-1998)
The book itself is the primary use. Chapters 2-12 of each edition build a complete Tiger compiler, and the per-chapter skeleton modules - lexer specification, grammar, abstract syntax, symbol tables, Temp and Tree modules, the runtime in C, and a set of sample .tig programs including the eight-queens solver that everyone who has read the book can recognise on sight - are still downloadable from Princeton in ML, C and Java flavours. The design was deliberately small but not toy: Appel notes that the language is "easily extensible to be functional, object-oriented, or both", which is exactly what Part II of the book goes on to do
The EPITA Tiger project
The largest sustained use of Tiger anywhere. Since approximately 2000, EPITA has run Tiger as a six-to-nine-month core-curriculum project in C++, with approximately 250 students a year, according to the 2008 paper, working in groups of four, a reference compiler (tc) maintained by the teaching staff, mentors drawn from the previous class, and its own dialect of the language documented in a "Tiger Compiler Reference Manual". Student extensions reported in the 2005 paper include object orientation, function overloading, an import feature, tail-recursion elimination, bounds checking and copy propagation; the same paper reports that one student wrote a Tiger front end for GCC and another rewrote their compiler in C# to learn the language
Tiger in Stratego (Utrecht University)
An independent Tiger compiler written entirely in Stratego, the strategic-rewriting language, as the flagship demonstration of the Stratego/XT transformation toolset. Its point is architectural rather than pedagogical: each compiler phase - desugaring, type checking, canonicalisation, instruction selection - is a separately packaged set of rewrite rules that can be recomposed, so the project doubles as an argument that compilation is program transformation. Release 1.2 dates from January 2003, and the project was documented on the program-transformation.org wiki associated with Eelco Visser's group
University compiler courses
Tiger became a default course project well beyond Princeton. Columbia's COMS W4115 under Stephen A. Edwards told students in 2002 that "you will implement a simple compiler for the Tiger language in a semester-long group project", and Edwards's three-page reference manual has since been reused by other courses; a Haverford College student submitted a Tiger program to the same catalogue in 2012, indicating the language was still being assigned in compiler courses then. Because the language is defined in ten pages and needs no library, it fits a semester in a way that a real language does not
Independent compiler implementations
The living record of Tiger is a long tail of personal projects: dozens of public repositories implementing Appel's language in Standard ML, OCaml, Haskell, Rust, C, C++, Java and Python, some following the book chapter by chapter, others retargeting it to LLVM or to x86-64 rather than the book's MIPS. They are the reason a language with no users, no releases and no organisation behind it still has code written for it nearly three decades after it was invented