Est. 1998 Advanced

Stratego

A domain-specific language for program transformation that separates rewrite rules from the strategies that control where and when those rules are applied

Created by Eelco Visser, with Zine-El-Abidine Benaissa and colleagues

Paradigm Declarative; strategic term rewriting (a functional, rule-based style)
Typing Dynamically typed terms (optional gradual typing added in the Stratego 2 line)
First Appeared 1998
Latest Version Stratego 2 (part of the Spoofax language workbench; 2.x series, actively maintained)

Stratego is a domain-specific language for program transformation—the systematic, rule-based rewriting of one program into another. Its defining idea is a clean separation between what to transform and where and when to do it: rewrite rules describe individual transformation steps as pattern-and-replace pairs, while strategies are small, composable programs that decide how those rules traverse and are applied across a program’s abstract syntax tree. This separation, unusual when Stratego appeared, lets a single library of rules be reused across many different transformations and lets generic control patterns—like “apply this everywhere, bottom-up” or “keep applying until nothing changes”—be written once, independently of the rules they orchestrate.

A note on dating

The encyclopedia metadata lists 1998 as Stratego’s first-appearance year, and independent verification supports it. Stratego is generally traced to the 1998 paper Building Program Optimizers with Rewriting Strategies by Eelco Visser, Zine-El-Abidine Benaissa, and Andrew Tolmach, presented at the ACM SIGPLAN International Conference on Functional Programming (ICFP'98). That work introduced the combination of named rewrite rules with a language of strategy combinators that became Stratego’s signature. The conceptual groundwork was laid slightly earlier, in the 1997 paper Specification of Rewriting Strategies by Bas Luttik and Eelco Visser. The frequently cited System Description of Stratego 0.5 dates to 2001 (RTA), which is the first tagged public release rather than the language’s first appearance. This page treats 1998 as the first-appearance year and flags the others in the timeline.

History & Origins

Stratego was created by the Dutch computer scientist Eelco Visser (1966–2022), initially during his time at Utrecht University and later carried forward at Delft University of Technology (TU Delft), where he became a professor and led the Spoofax language-workbench effort. Its intellectual roots lie in the world of algebraic specification and term rewriting, and in particular the ASF+SDF meta-environment developed in Amsterdam, which used equations (rewrite rules) to define and manipulate languages.

Pure term rewriting has a well-known limitation: a plain rewrite system applies its rules according to a fixed, built-in strategy (such as innermost or outermost evaluation), giving the programmer little control over where rules fire. For many program transformations—optimizers especially—that control is exactly what you need. Visser’s insight, developed with collaborators including Zine-El-Abidine Benaissa and building on the strategy-specification work with Bas Luttik, was to make the traversal and application strategy itself a first-class, programmable object. The result, presented at ICFP'98 and refined over the following years, was Stratego.

Design Philosophy

Stratego’s design turns on a single principle: separate transformation rules from transformation control.

  • Rules say what changes. A rewrite rule matches a term against a pattern and produces a replacement. Rules are small, local, and reusable.
  • Strategies say how change spreads. A strategy is a program built from a handful of combinators—sequence, choice, and generic traversal—that determines how rules are applied across the whole tree.

From this separation flow the language’s other commitments:

  • Generic traversal. Rather than hand-writing recursion for every tree shape, Stratego provides one-level traversal combinators (all, one, some) from which language-independent traversals like “transform everything bottom-up” (bottomup) or “innermost normalization” (innermost) are defined once and reused for any language.
  • Composability. Strategies combine with sequential composition (;), deterministic choice (<+), and recursion, so complex transformations are assembled from simple, well-understood parts.
  • Terms as the universal data structure. Programs are represented as first-order terms (the ATerm format in Stratego/XT), which lets tools exchange abstract syntax trees and lets generic strategies operate on any language.

Key Features

  • Rewrite rules of the form Name: lhs -> rhs, optionally with a where clause for side conditions and computed bindings.
  • Strategy combinators for control flow: sequence s1 ; s2, guarded/left choice s1 <+ s2, negation-by-failure, and recursive strategy definitions.
  • Generic one-level traversal (all(s), one(s), some(s)) that applies a strategy to a term’s direct subterms without knowing their shape—the foundation of reusable, language-independent traversals.
  • Match and build primitives (?pattern and !pattern) that decompose the language into its most elementary operations, from which rules are derived.
  • Dynamic rewrite rules, which can be generated at runtime to carry context-sensitive information (for example, remembering a variable’s value while transforming the code that uses it).
  • Concrete object syntax, letting rule patterns be written in the syntax of the language being transformed rather than in raw abstract-syntax terms—a feature developed with SDF-based parsing.
  • The Stratego/XT toolset, a collection of components—parsers, pretty-printers, and generic libraries—for assembling complete transformation systems around Stratego specifications.

A tiny flavor of the language, defining constant folding as a rule plus a strategy that applies it everywhere until no further change is possible:

// A rule: rewrite the addition of two integer literals
EvalPlus:
  Plus(Int(i), Int(j)) -> Int(<addS>(i, j))

// A strategy: apply EvalPlus everywhere, repeatedly, until fixpoint
simplify = innermost(EvalPlus)

Evolution

Stratego evolved across a sequence of releases and an accompanying toolset:

MilestoneApprox. yearNotes
First appearance (ICFP'98)1998Rewrite rules + strategy combinators introduced
Stratego 0.5 (RTA system description)2001First widely cited tagged release
Stratego/XT tutorial (LNCS)2004Toolset-oriented consolidation
Stratego/XT 0.162006Restructured into reusable components
Stratego/XT 0.17 (Sci. Comput. Program.)2008Comprehensive language-and-toolset description
Spoofax integration2010Stratego embedded in an Eclipse-based workbench
Stratego 2 / gradual typing2020–Gradual type system and incremental compiler

The most significant shift over time has been the move from the standalone Stratego/XT toolchain—which compiled specifications (historically via C) and exchanged trees using the ATerm format—into the broader Spoofax language workbench, where Stratego serves as the transformation and semantics language alongside SDF-based syntax definition. The more recent Stratego 2 line, associated with Jeff Smits and Eelco Visser’s work on gradually typing strategies (SLE 2020), adds an optional type system so that the shapes of terms and transformations can be declared and checked, addressing a long-standing weakness of the originally untyped language.

Current Relevance

Stratego remains actively developed and used, primarily through Spoofax. In that setting it is a practical tool for language engineering: researchers and students designing their own domain-specific languages use Stratego to implement desugaring, name and type analysis, optimization, and code generation. Its most visible downstream application is WebDSL, a web-programming language whose compiler is built with Stratego transformations. Following Eelco Visser’s death in 2022, the Programming Languages group at TU Delft and the wider Spoofax community have continued to maintain the language and its ecosystem.

Because it targets a specialized problem—transforming programs and building compilers and DSLs—Stratego has never been a general-purpose or mainstream language. But within its niche it is highly regarded, and its ideas have spread: the strategic-rewriting approach influenced later meta-programming systems such as Rascal, and the turtles-all-the-way-down notion that traversal control should itself be programmable has become a standard part of the program-transformation vocabulary.

Why It Matters

Stratego’s contribution is conceptual as much as practical. Before it, term rewriting forced a false choice between the elegance of declarative rules and the control you need to build real transformations; you either accepted a fixed evaluation strategy or abandoned rewriting for hand-written recursive code. Stratego showed that the strategy could be a program too—first-class, composable, and reusable—so that a library of small rules and a library of generic traversals could be combined in endless ways. That separation of rules from strategies, together with generic one-level traversal combinators, is the idea most cited from Stratego, and it reshaped how the software-language-engineering community thinks about building compilers, optimizers, refactoring tools, and domain-specific languages. For a language born to build program optimizers, its most lasting optimization may have been to the discipline of program transformation itself.

Timeline

1997
Bas Luttik and Eelco Visser present "Specification of Rewriting Strategies" at the ASF+SDF'97 workshop in Amsterdam, laying the conceptual groundwork for programmable strategies
1998
Stratego first appears in Visser, Benaissa, and Tolmach's paper "Building Program Optimizers with Rewriting Strategies" at ICFP'98, introducing named rewrite rules combined with strategy combinators
2001
The system description of Stratego 0.5 is published at the 12th International Conference on Rewriting Techniques and Applications (RTA 2001)
2004
The tutorial "Program Transformation with Stratego/XT" appears in the Domain-Specific Program Generation LNCS volume, consolidating the Stratego/XT toolset around the language
2006
Stratego/XT 0.16, "Components for Transformation Systems" (Bravenboer, Kalleberg, Vermaas, Visser), is presented, restructuring the toolset into reusable components
2008
"Stratego/XT 0.17: A Language and Toolset for Program Transformation" is published in Science of Computer Programming
2010
The Spoofax language workbench (Kats and Visser, OOPSLA 2010) integrates Stratego with SDF-based syntax definition inside Eclipse, broadening its audience
2020
Smits and Visser present "Gradually Typing Strategies" at SLE 2020, introducing a gradual type system whose incremental compiler underpins the Stratego 2 line
2022
Eelco Visser, Stratego's principal designer, dies on 5 April; the language and the wider Spoofax project continue under the Programming Languages group at TU Delft

Notable Uses & Legacy

Spoofax language workbench

Stratego is the transformation and semantics language inside Spoofax, used to define name resolution, desugaring, and code generation for user-defined domain-specific languages

Stratego/XT toolset

A collection of tools and libraries for building program transformation systems—parsers, pretty-printers, and generic language-processing strategies—all driven by Stratego specifications

WebDSL

A domain-specific language for building web applications, developed at TU Delft, whose compiler is implemented using Stratego transformations

Compiler and optimizer construction

Stratego's original motivation was building program optimizers; it is used in research and teaching to express constant folding, inlining, dead-code elimination, and other passes as rewrite rules with explicit traversal strategies

Academic research in program transformation

Widely used in the software language engineering research community to prototype refactorings, analyses, and source-to-source translations

Language Influence

Influenced By

ASF+SDF Term rewriting systems ELAN

Influenced

Spoofax Rascal Stratego 2

Running Today

Run examples using the official Docker image:

docker pull
Last updated: