TOM
Tom is a pattern matching compiler built at LORIA and Inria in Nancy that grafts term rewriting onto Java and C: %match, algebraic signatures, backquote term construction, rewrite rules and a strategy library, compiled away into ordinary host-language code so that rewriting techniques could be used inside real applications instead of inside a dedicated interpreter
Created by Pierre-Etienne Moreau, who led the work and wrote most of the compiler, at the Protheo and later Pareo research groups of LORIA and Inria Nancy - Grand Est, in France. The project AUTHORS file credits the "initial design of Tom" jointly to Christophe Ringeissen and Marian Vittek, and lists Emilie Balland, Jean-Christophe Bach, Horatiu Cirstea and Antoine Reilles as the other main developers, with Paul Brauner, Julien Guyon (the Eclipse plugin), Radu Kopetz (compiler and anti-patterns), Claudia Tavares (type inference) and Marc Pantel (model transformations and the Ada backend) among the contributors. Mark van den Brand, Jurgen Vinju, Patrick Viry and Eelco Visser are thanked in the same file for discussions - Visser specifically beside the %match construct, Viry beside the backquote notation
Tom is what happens when a group of rewriting researchers stop trying to make people come to their language and go to everybody else’s instead. Built at LORIA in Nancy from around 2000 and developed at Inria for the better part of two decades, Tom takes the machinery of term rewriting — algebraic signatures, pattern matching modulo equational theories, rewrite rules, traversal strategies — and grafts it onto Java. A .t file is a Java file with extra constructs in it; the tom command expands those constructs into ordinary Java and hands the result to javac. Nothing is interpreted and no foreign engine takes over at run time, though generated code does link against Tom’s own runtime library (tom-runtime-full.jar, on the CLASSPATH); and in principle an ordinary Java program is already a valid Tom program, since the compiler expands only the constructs it recognises and passes the rest through untouched.
The name is an acronym, and a slightly apologetic one. The project’s own about page explains it: “In its first version, Tom was just supposed to add pattern matching facilities to a programming language. The considered pattern matching feature was supposed to discriminate over a single subject. This is why Tom is called Tom: To One Matching.”
Dating the language
Language lists give 2000, and the project’s own copyright line supports it: the LICENCE file in the source tree reads “Copyright (c) 2000-2015, Universite de Lorraine, Inria”. But nothing dated 2000 survives in the code. The oldest record in the tree is the ChangeLog, and it opens on 25 January 2001 with a single line — “Setup of TOM under automake” — followed on 6 February by the first JavaCC parser and on 14 February 2001 by an entry that reads, in full, “src/jtom/Tom.java: first bootstrap”. The first publication, “A Pattern Matching Compiler” by Pierre-Étienne Moreau, Christophe Ringeissen and Marian Vittek, was presented at the first LDTA workshop in Genova in April 2001.
Version numbers arrive late and start low. The ChangeLog dates version 0.6 to 29 October 2002 (it introduces the backquote notation), version 0.7 to 19 November 2002 (“bootstrap with ApiGen”), and 1.0beta to 21 November 2002. The safest reading is that 2000 is when the design work began, 2001 when there was a working compiler, and 2002 when it started being versioned for other people.
Where it came from: the ELAN lesson
Tom’s ancestry is explicit. The Protheo group at LORIA had spent the 1990s building ELAN, a rewriting language with non-deterministic strategies and a compiler for associative-commutative rewriting that was, along with Maude, among the most serious implementations of its kind. The Tom about page states the lineage directly: Tom’s “design follows our research on rule based languages, and our experiences on the efficient compilation of ELAN”.
What the group took from ELAN was less a technique than a disappointment. The RTA 2007 system description sets it out plainly: implementing a good term data structure is hard, marshalling data in and out of a rewriting engine is often the bottleneck, built-in integers and doubles are awkward, mutable structures like arrays are essential and missing — “but one of the most important things we learned is that even if efficiency is important to make our technology credible, integration capabilities are even more important to make our research widely used both in academic and industrial projects.”
The alternative to piling libraries, threads, GUIs and native interfaces onto a research language was to stop competing with Java. The group called the resulting idea a formal island: a fragment of formally-defined, rule-based code embedded in an ordinary program, connected to the surrounding data by a formal anchor — a mapping that explains how an existing concrete data structure is to be read as an algebraic term. The idea is related to Wadler’s views, and its practical effect is that Tom can rewrite data structures it did not create, without converting them first.
What the language adds
The whole language is a handful of constructs. The canonical example from the project’s guided tour defines a signature and matches on it:
| |
The moving parts:
| Construct | What it does |
|---|---|
%match | The core. Like ML’s match, but discriminating over algebraic terms rather than atomic values, and falling through to the next pattern if the action does not break the control flow |
` (backquote) | Builds terms, and reads the variables bound by a pattern back into host-language expressions |
%gom / Gom | Declares an algebraic signature and generates the Java classes implementing it, with maximal sharing |
%typeterm, %op | The mapping, or formal anchor: how to see a data structure you already have as a term you can match on |
%strategy, the sl library | Traversal and control: TopDown, BottomUp, Repeat, Choice, All, and user-defined combinators, applied to terms as first-class strategy objects |
! | Anti-patterns — matching terms that do not have a given shape, added in version 2.4 |
%transformation, %resolve, %tracelink | Model-to-model transformation with traceability, added in the final release |
Two properties follow from Gom’s term representation, inherited from CWI’s ATerm and ApiGen work: terms are maximally shared — the property inherited from CWI’s ATerm library, under which no two structurally equal subterms are ever separately allocated, so that testing structural equality is a pointer comparison rather than a traversal — and lists can be normalised with respect to equational axioms — associativity, associativity with neutral element, and (from 2.8) associativity-commutativity — so that matching happens modulo those theories rather than syntactically.
Evolution
| Release | Date | What it brought |
|---|---|---|
| 0.6 / 0.7 / 1.0beta | Oct–Nov 2002 | Backquote notation; bootstrap on ApiGen; first stable numbering |
| 1.5 | 10 Dec 2003 | New checker, XML syntax for patterns, Eclipse plugin days later |
| 2.0 | 9 Jun 2004 | Caml support, optimizer, built-in char and string, redesigned kernel compiler |
| 2.1 | 20 Dec 2004 | ANTLR parser, plugin architecture, first traversal strategy library |
| 2.2 | 29 Jul 2005 | %typeterm unification, second optimization level |
| 2.3 | 28 Apr 2006 | Gom, %strategy, %[...]% backend-writing construct |
| 2.4 | 4 Oct 2006 | Anti-patterns, sort inference for subjects, bytecode support, Eclipse plugin revived |
| 2.5 | 9 Jul 2007 | Constraint-based compiler, associative matching with neutral element, sl library |
| 2.6 | 11 Apr 2008 | Matching constraints p << t with && / ||, mapping inlining, ANTLR adapter |
| 2.7 | 25 May 2009 | Fresh names and binders in Gom, generics in strategies, parallel compilation |
| 2.8 | 14 Feb 2011 | AC matching, new type inference, Tom–EMF bridge |
| 2.9 | 14 Oct 2011 | Non-linear AC patterns, default values in %op, alpha ANTLR v3 parser |
| 2.10 | 21 Mar 2013 | Subtyping type engine by default, Ada backend, %transformation / %resolve / %tracelink |
The backend story is messier than the release notes suggest. Java was always the supported target; the source tree also carries generators for C, C#, Caml, Python and - from the final release of 2013, according to NEWS - Ada, of varying completeness, and the manual is candid that the model-transformation constructs of the last release work “only [for] Java and EMF”. The installation guide in doc/ gives the requirement as a development kit “version 1.5 or newer”, and reports that Tom “has been used successfully on many platforms, including GNU/Linux distributions (Debian, Gentoo, Mandrake, Ubuntu), MacOS X, FreeBSD, NetBSD, Windows XP, Windows Vista and Windows 7” — a list of platforms the project says it was used on rather than a supported-platform matrix.
The decline
Tom did not fail; it stopped. Version 2.10 shipped on 21 March 2013 and no release followed. The ChangeLog runs on to August 2013, the master branch to December 2017, a v3 branch to August 2019, and build.xml still names an unreleased 3.0-dev. Then the infrastructure went: Inria took gforge.inria.fr off-line at the end of 2020, and with it every download link, the Windows installer, the bug tracker and the git URLs printed all over the project’s pages. The site at tom.loria.fr is still served, but what is served is a static HTTrack copy of it made on 1 March 2023, complete with dead links to the forge. Tom does not appear ever to have been published to Maven Central — nothing is served under the obvious group IDs — so there is no package-manager fallback either.
What survives is the source. A mirror of the repository was created on GitHub in February 2016 and is complete back to the CVS-to-Subversion import of 8 January 2003, with the pre-2003 history preserved in the ChangeLog. And in May 2026, over three days, Pierre-Étienne Moreau pushed 63 commits to a branch called tom-go: the ATerm library, the parser, the Gom backend and the compiler phases ported to Go, with the commit messages tracking parity against the Java implementation test by test. It is branch work, unreleased and unannounced, and it would be wrong to call it a revival — but it is the only movement in the project since 2019, and it is by the person who started it.
Why it matters
Tom is the most fully worked-out answer to a question the programming-language research community keeps running into: what do you do when your ideas are good and nobody will switch languages to get them? The formal-island approach — put the formal fragment inside the industrial language, connect it to existing data through a mapping rather than a conversion, compile it away to nothing — let a rewriting group ship pattern matching, equational matching, rewrite rules and strategy combinators into Java projects the best part of two decades before Java itself got pattern matching, and let those projects keep their own data structures while doing it.
It is also a good specimen of how such a project actually ends. There was no fork, no schism, no successor language: there was a research group whose people finished their theses and moved on, a series of releases that got steadily better and steadily more specialised, one clearly documented industrial engagement, and finally a hosting service being decommissioned. The compiler is four fifths written in itself, which is the sincerest thing a language designer can say about a design; the tarballs it was distributed in are gone; and the whole of it now fits in a git clone.
Running Tom today
There is no Docker image and no official download. What is available:
- The source.
git clone https://github.com/rewriting/tom.gitgives the full history, the Ant build (./build.sh), the manual underdoc/, and the examples and regression tests. Building it requires a JDK and bootstrapping through the checked-in stable compiler; the tree was last built against Java 8 and would need care on a modern JDK. - The documentation. The reference manual, guided tour and FAQ are in the repository as Markdown under
doc/, and the 2.7-era manual PDF is deposited in Inria’s HAL archive. - The web site, tom.loria.fr, as a frozen 2023 mirror: news log, applications, licensing, and the Emacs, Vim and Notepad++ syntax files, which are among the few links on it that still resolve.
The licence remains the one the project settled on in 2005: GPL v2 for the compiler, BSD for the runtime library and the predefined mappings, precisely so that anything Tom generates can be redistributed under whatever licence its author prefers.
Timeline
Notable Uses & Legacy
The Tom compiler itself
Tom bootstrapped on 14 February 2001 and stayed bootstrapped: the compiler is a chain of transformations over its own abstract syntax tree, written in Tom, compiled by the previous Tom. The project's own SLOCCount run of 6 March 2014 puts src/tom at 59,361 lines - 46,996 of Tom, 7,573 of Java, plus the Ada and Python runtime pieces - which makes the compiler the largest and best-documented Tom program in existence, and the reason the project's applications page calls it "the most famous application" of Tom
Airbus and Ellidiss - model transformation for avionics
The clearest industrial trace. "Tom-based tools to transform EMF models in avionics context", by Jean-Christophe Bach, Pierre-Etienne Moreau and Marc Pantel, presented at the industrial track of Software Language Engineering on 25 September 2012, describes using Tom's rule-based approach to implement and trace the transformations that take a system model written in an engineering language into the formal languages a model checker can verify - work done "in a research project involving industrial partners: Airbus and Ellidiss", where the transformation step itself has to be qualifiable for certification. The %transformation, %resolve and %tracelink constructs released in Tom 2.10 came out of this line of work
Java bytecode analysis and rewriting
From version 2.4 Tom shipped support for treating compiled Java bytecode as terms, with the mapping layer standing in for a parser. Emilie Balland, Pierre-Etienne Moreau and Antoine Reilles described the approach in "Bytecode Rewriting in Tom" at the Bytecode workshop in Braga in 2007: patterns are written over instruction sequences and strategies drive the traversal, so that analyses and instrumentation can be expressed as rewrite rules rather than as visitor code
Rule-based protocol verification
Horatiu Cirstea, Pierre-Etienne Moreau and Antoine Reilles used Tom to encode and re-verify the Needham-Schroeder public-key protocol, presented as "Rule based programming in Java for protocol verification" at the 5th International Workshop on Rewriting Logic and its Applications in Barcelona in 2004. The point of the exercise was the division of labour Tom was built for: rewrite rules describe the transitions of the system, while the search strategies over them - depth-first, breadth-first, parallel - are written and executed separately
Embedding Tom in other host languages - the GLL experiment
"Island Grammar-based Parsing using GLL and Tom" (SLE 2012), by Ali Afroozeh, Mark van den Brand and Maarten Manders at TU Eindhoven, Adrian Johnstone and Elizabeth Scott at Royal Holloway, and Bach and Moreau at Inria, used Tom as the case study for a hard parsing problem: embedding one language inside another recursively produces a nondeterministic composite grammar, exactly the situation Tom's own parser faces when Tom constructs are scattered through Java or C source. The paper is a good measure of how much of Tom's difficulty was in the host-language embedding rather than in the matching
Rewriting research: deep inference, anti-patterns, the rho-calculus
Tom's main constituency was the rewriting community that built it. "Implementing Deep Inference in Tom" (Ozan Kahramanogullari, Moreau and Reilles, ICALP Structures and Deduction workshop, 2005) used it for proof-theoretic search; "Anti-Pattern Matching" (Claude Kirchner, Radu Kopetz and Moreau, ESOP 2007) introduced into Tom the negative patterns that few other languages have; and the project's own applications page records a first implementation of the rho-calculus, propositional provers, and encodings of L-systems and of the BoulderDash gravity rule written in Tom