Decaf
A family of small, Java-flavored teaching languages built so that a single student, or a small team, can write a complete working compiler for them in one term.
Created by University compiler-course staff; the widely circulated object-oriented variant comes from Stanford's CS143, whose Decaf specification handout is credited to Julie Zelenski and was later updated by Jerry Cain and Keith Schwarz
Decaf is not one language. It is a name that a generation of compiler instructors independently gave to the same idea: take Java, remove almost everything, and leave behind exactly enough language that a student can compile all of it in a single term. The name is the joke and the specification at once - Java with the caffeine taken out.
What survives that subtraction differs from campus to campus. Stanford’s Decaf keeps classes, single inheritance, interfaces, and dynamic dispatch, and asks students to emit MIPS assembly. MIT’s Decaf drops object orientation almost entirely: a program is one class named Program, holding fields and methods, with int and boolean scalars and fixed-size arrays. Simon Fraser’s uses a func keyword and extern declarations so student compilers can call into the C library. James Madison’s is smaller still. They are separate languages that share a name, a purpose, and a family resemblance to C and Java.
History and Origins
Decaf’s origins are genuinely murky, which is itself characteristic of teaching languages: they are written as course handouts, revised each offering, and rarely announced anywhere a bibliography would catch. Specifications were circulating in the early 2000s, and the date usually attached to the language - around 2002 - should be treated as approximate rather than as a release date.
The best-documented lineage is Stanford’s. When CS143 closed its Summer 2008 offering, the course page thanked Steve Freund, Maggie Johnson, Julie Zelenski, and Jerry Cain for “building up the handouts, Decaf specification, and projects” over years of preparation - a description of accumulated revision, not a single authorship event. The specification handout itself is credited to Zelenski and was later updated by Cain and Keith Schwarz; the edition most people encounter today is dated June 27, 2012.
A second, unrelated line runs through the University of Tennessee, Knoxville, where Brad Vander Zanden devised a much smaller Decaf that other schools picked up. Southern Adventist University’s CPTR 415 handout credits him directly and describes a language with only int and void primitives, classes, and one-dimensional arrays - inheritance, interfaces, constructors, exceptions, and garbage collection all deliberately absent.
MIT’s 6.035 developed a third variant on its own track, and Tsinghua University a fourth. That so many courses converged on both the design and the name says something about how obvious the design problem is once you have taught the course.
Design Philosophy
Every Decaf is an answer to one question: what is the smallest language that still forces a student to solve every interesting problem in compilation?
The features that survive are the ones that teach something:
- A static type system - so students must build a symbol table, implement scoping rules, and report type errors rather than trusting the runtime.
- Classes and inheritance (in the Stanford lineage) - so students must lay out objects in memory, build virtual method tables, and implement dynamic dispatch.
- Arrays with runtime bounds - so students must generate bounds checks and think about heap allocation.
- Ordinary control flow and function calls - so students must design a stack frame layout and honor a calling convention.
The features that get cut are the ones that mostly add engineering weight: generics, exceptions, threads, overloading in most variants, packages and separate compilation, string manipulation beyond literals, and - in nearly every edition - garbage collection. Decaf programs typically leak, and in the editions that address it at all this is stated as a deliberate simplification rather than an oversight.
The result is a language a student can read in an afternoon and a compiler a student can finish in a term.
Key Features
The Stanford-style Decaf is the richest of the common variants. Its keyword list includes void, int, double, bool, string, class, interface, null, this, extends, implements, for, while, if, else, return, break, and new, alongside the built-in library functions Print, ReadInteger, ReadLine, and NewArray.
| Area | What Decaf provides |
|---|---|
| Primitive types | int, double, bool, string, plus void for method returns |
| Reference types | Classes and arrays; null for both |
| Inheritance | Single inheritance via extends, with interfaces via implements |
| Arrays | Declared with [] and heap-allocated through the NewArray built-in; most course projects exercise only the one-dimensional case |
| I/O | The Print, ReadInteger, and ReadLine library functions |
| Comments | C-style // line and /* */ block comments |
The built-ins are deliberately spartan. According to the Stanford specification, Print accepts arguments of string, int, or bool type; ReadInteger reads a line of user input and converts it with atoi, yielding 0 when the input is not a valid number; NewArray takes an integer length and a non-void element type and returns an array of that type.
A short program in the Stanford style looks like this - the exact form of allocation and of the program entry point varies slightly between editions, so treat this as illustrative of the flavor rather than as a portable snippet:
| |
Anyone who has written Java will recognize all of it, which is the point: no student should spend project time learning the source language.
Evolution
Decaf has no versions, no committee, and no standard. It evolves by fork. Each course takes a specification it likes, cuts or adds what its own syllabus needs, and reissues it under the same name - which is why “the Decaf grammar” is an ambiguous phrase and why student code written for one course will not compile under another course’s rules.
The trajectories of the major variants diverge sharply:
- Stanford retired Decaf. By Summer 2014, CS143 was distributing Cool reference materials instead, and the course has stayed with Cool since. The Decaf handouts remain online in Stanford’s class archive and are still widely used for self-study.
- MIT kept it. Decaf has been the 6.035 project language across the editions published on OpenCourseWare, and it carried over when the course was renumbered 6.110; the Spring 2025 syllabus still points students at a Decaf specification.
- Tsinghua modernized it. In 2019 the decaf-lang organization published the compiler framework three times over - in Scala, in “modern” Java, and in Rust - so that students could choose their implementation language. In July 2020 the same group introduced MiniDecaf, a further-reduced teaching language - its tutorial presents it as a subset of C compiled down to RISC-V assembly - with its own tutorial, starter code, and test suite, and those course repositories have continued to be updated in the years since.
Current Relevance
Decaf occupies an odd position: nothing is written in it, and yet it is compiled constantly. It has no package ecosystem, no standard library worth the name, no runtime anyone maintains for its own sake, and no Docker image. Every implementation that exists is a student’s or an instructor’s.
Judged as a production language it is dead and always was. Judged as classroom infrastructure it is very much alive - assigned at MIT as recently as Spring 2025, maintained at Tsinghua in three host languages, and used at a long tail of other departments, each with its own reference document. The archived Stanford handouts, meanwhile, have had a second life as a self-study project for programmers who want to write a real compiler without enrolling anywhere, and GitHub carries a steady supply of independently written Decaf compilers targeting MIPS, x86, and LLVM.
Why It Matters
Teaching languages are the least glamorous artifacts in language design and among the most consequential. A large share of working compiler engineers first implemented dynamic dispatch, first laid out an activation record, and first watched their own generated assembly run because a handout told them to do it for Decaf.
Decaf also demonstrates an underappreciated design skill: knowing what to leave out. Cutting Java down to something compilable in ten weeks - while keeping inheritance, static typing, and heap allocation, so that the exercise stays honest - is a real design problem, and the fact that several faculties solved it independently and landed on such similar answers suggests they were all finding the same natural minimum.
Its fragmentation is instructive too. Decaf is a case study in what happens to a language with no standards body: a shared name covering a dozen incompatible dialects, each perfectly adequate for its own audience and useless outside it. For a language whose users graduate every spring, that turns out to be exactly the right amount of governance.
Timeline
Notable Uses & Legacy
Stanford CS143 - Compilers
For roughly a decade Stanford's undergraduate compilers course was built around Decaf: students wrote a lexer, a parser, a semantic analyzer for a language with classes, single inheritance, and interfaces, and a code generator producing MIPS assembly. Student extensions ranged from optimization passes to Decaf-to-C++ translators.
MIT 6.035 / 6.110 - Computer Language Engineering
MIT's compilers course uses a different, imperative Decaf in which the whole program is one class named Program, with int and boolean scalars and fixed-size arrays. It is a team project spanning scanning, parsing, semantic checks, code generation, and optimization, and the 2005 and 2010 editions are published on OpenCourseWare.
Tsinghua University compilers course and the decaf-lang project
The Tsinghua Decaf framework is maintained publicly on GitHub, with the same language implemented three ways - in Java, Scala, and Rust - so students can pick a host language for their programming assignments, which run from parsing through type checking, three-address code, and MIPS assembly emission.
James Madison University CS 432 / CS 630
Mike Lam's courses use a compact Decaf with int and bool types, functions, and arrays, backed by a locally maintained language reference and a project sequence that walks students from a hand-written scanner to a working compiler.
Simon Fraser University CMPT 379
Anoop Sarkar's compilers class uses a Decaf with func declarations, extern functions for linking against C library routines, and int, bool, string, and void types, plus one-dimensional arrays. The published specification credits its course-materials code as forked from the Johns Hopkins machine-translation class code by Matt Post and Adam Lopez.
Independent compiler projects on GitHub
Because published Decaf specifications are short and self-contained, they are a common target for self-directed learning. Public repositories include Decaf compilers written by students following the archived Stanford handouts, as well as reimplementations targeting MIPS, x86, and LLVM.