Est. 1997 Intermediate

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"

Paradigm Imperative and procedural, but expression-oriented: a Tiger program is a single expression, and control constructs, assignments and let-blocks are all expressions rather than statements. Appel describes it on his own site as "a simple Algol-like language with heap-allocated records that is easily extensible to be functional, object-oriented, or both"; Akim Demaille, who has reportedly taught it to several thousand students, calls it "a small yet very complete subset of Pascal dressed in a clean ML-like syntax". Catalogue entries filing it under Scripting are wrong: Tiger has no interactive interpreter, no dynamic evaluation and no host application to script - it is a compiled language whose reference implementations emit machine assembly, most often for MIPS
Typing Static, strong and monomorphic. Two predefined types, int and string, plus user-declared record and array types. Types are distinct by declaration, not by structure - two records with identical fields are different types - and a sequence of type declarations may be mutually recursive provided every cycle passes through a record or an array. There are no floating-point numbers, no explicit pointers and no generics; records and arrays are heap-allocated and compared by reference, and nil is a value of record type. The language assumes a garbage collector, which is the subject of the book's Chapter 13
First Appeared 1997, in the preliminary editions of Appel's textbook - published by Cambridge University Press as Modern Compiler Implementation in Java: Basic Techniques and its C and ML counterparts. The definitive statement of the language is Appendix A, the "Tiger Language Reference Manual", of the full 1998 editions. Catalogue entries giving only "1990s" are not wrong, merely vague; no public document places Tiger before 1997, though it is likely to have been used in Appel's Princeton compilers course while the book was being written
Latest Version None, and by design. Tiger has never been versioned, standardised or revised: the 1998 Appendix A is still the definition, and the only changes since have been other people's dialects. The best-documented of these is the EPITA variant defined by the "Tiger Compiler Reference Manual" (the Texinfo source on EPITA's server is stamped 16 May 2003), whose reference compiler tc ships class-year distributions - the last ones publicly served are labelled 2020 and 2021, uploaded in 2018 and 2019. Appel himself moved on: the second edition of the Java book (with Jens Palsberg, 21 October 2002) replaced Tiger with MiniJava, a subset of Java, while the ML and C editions kept Tiger and remain in print

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:

FeatureTiger
Predefined typesint, string — and nothing else; no floats, no booleans
Constructed typesrecords (named, typed fields) and arrays, both heap-allocated
Type identityby declaration, not structure: two records with identical fields are different types
Recursionmutually recursive types allowed in a declaration sequence, if every cycle passes through a record or array
Truthzero is false, everything else is true; & and `
Equality= and <> on any two values of the same type; records and arrays compare by reference
Functionsnested, lexically scoped, mutually recursive within a declaration sequence, arguments by value
Memoryassumed 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 Tree intermediate 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 %destructor directive 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

1997
Tiger appears in print. Cambridge University Press publishes the preliminary editions of Appel's textbook - Modern Compiler Implementation in Java: Basic Techniques and the matching C and ML volumes - containing Part I only plus five chapters of Part II. The book site, captured by the Internet Archive on 7 June 1997, carries a 1997 copyright line and already offers the per-chapter Tiger compiler modules for download; the ML skeleton is later stamped "Last updated November 10, 1997" and requires Standard ML of New Jersey 109.32
1998
The full first editions appear, copyright 1998: Modern Compiler Implementation in Java, in ML, and in C (the last with Maia Ginsburg). Appendix A, the "Tiger Language Reference Manual", runs to ten pages - 512 to 521 in the ML edition - and is the definition of the language to this day. Chapters 2 through 12 walk the reader through a complete Tiger compiler: lexer, LR parser, abstract syntax, type checker, activation records, IR trees, canonicalisation, instruction selection, liveness analysis and graph-colouring register allocation, ending in assembly for a real machine - the targets worked through in the text are MIPS and Sparc
1999
The first editions are reprinted with corrections. Appel's errata page splits into three lists - the preliminary 1997 "Basic Techniques" edition, the 1998 first printing, and the 1999 corrected reprint - which is how a reader can still tell which Tiger definition their copy contains
2000
Approximately: EPITA, a French private engineering school, adopts Tiger for the long project of its core curriculum. Demaille's 2005 paper dates the decision to "five years ago" and explains that compiler construction was chosen "for reasons not related to compiler construction" - the real goals being C++, object-oriented design, design patterns, documentation, testing and nine months of team work. Tiger was picked because Appel's book was the right size and because Tiger is "rich enough so that compiling higher level languages to Tiger is not needed"
2001
30 April: the earliest dated Tiger project artefact still served from EPITA's web server, a design document filed as tigdes_20010430_v11.pdf. A 2003 student free-topic assignment on the same server proposes a Tiger virtual machine
2002
21 October: Cambridge publishes the second edition of Modern Compiler Implementation in Java, by Appel with Jens Palsberg, in which the project language is no longer Tiger but MiniJava, a subset of Java - the appendix is retitled the "MiniJava Language Reference Manual". The ML and C editions keep Tiger. In the same period Stephen A. Edwards uses Tiger for the semester project of Columbia's COMS W4115, writing the compact three-page restatement of the reference manual that is, to this day, the version of the Tiger specification most people actually read
2003
January: version 1.2 of "Tiger in Stratego", an independent Tiger compiler built at Utrecht University as a showcase for the Stratego/XT program-transformation system, is released; the project wiki, maintained within Eelco Visser's group, documents a componentised compiler in which every phase is a rewriting strategy and which produces MIPS code for the SPIM simulator. On 16 May the EPITA "Tiger Compiler Reference Manual" is stamped with a new edition; it warns students to "pay extreme attention to implementing the version of the language specified below, not that of the book", the EPITA dialect having changed the string escapes, the end-of-line handling and more
2005
12 June: Laurent Le Brun submits a recursive Tiger implementation of 99 Bottles of Beer to 99-bottles-of-beer.net as entry 746, pointing at tiger.lrde.epita.fr - the submission through which Tiger entered the language catalogues, complete with the "scripting" misclassification it has carried ever since. Later that month, at ITiCSE'05 in Portugal, Demaille presents the EPITA project publicly for the first time
2008
At ITiCSE'08 in Madrid, Demaille, Levillain and Perrot describe the tooling the project grew: Havm (an interpreter for Appel's Tree intermediate language, so that students can run and test the middle of their compiler), Nolimips (a MIPS simulator that can be told to expose fewer registers than the real machine, so that register-allocation spills can actually be provoked), a C++ fork of the Mono project's Monoburg instruction-selector generator, a private AST generator, and a series of contributions to GNU Bison. They report a scale unusual for a compiler course: about 250 students a year, in groups of four, making around a dozen submissions - "more than 2000 (proto-)compilers to assess each year"
2018
EPITA is still shipping Tiger. The tc distributions publicly served from the project directory are labelled by class year: the six-stage 2020 series was uploaded between January and May 2018, and a 2021 series in April 2019. The auxiliary tools were refreshed alongside and after them: Monoburg 1.0.7 is dated March 2019, and Havm 0.28 and Nolimips 0.11 carry December 2021 file dates - the most recent activity visible in the directory
2026
Tiger has no vendor, no community and no releases, yet new Tiger compilers keep appearing: a GitHub search for repositories mentioning Appel and Tiger returns dozens, in ML, OCaml, Haskell, Rust, C, C++, Java and Python, with pushes as recent as August 2026. The language is frozen; the exercise is not

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

Language Influence

Influenced By

Running Today

Run examples using the official Docker image:

docker pull
Last updated: