Racket
#lang modules — using exactly the machinery the built-in languages use. Macros, syntax objects, modules, and a full IDE make it the classic platform for language-oriented programming.
Purpose
Racket is a language for making languages, so your DSL is a first-class module instead of a string parsed by a library.
The Problem It Solves
In most languages a DSL means writing a parser for strings and hoping the tooling behaves. Racket turns language design into ordinary programming: a #lang is a real language with its own syntax, its own error messages, and IDE support — implemented as macros over Racket’s core. The Racket compiler becomes your interpreter, so you extend the language instead of re-implementing one.
Where It Fits
Compared with the other pages in this trio: ANTLR generates the recognizer for a grammar you declare; OCaml gives you a type-safe language to implement a compiler in; Racket is the fastest environment for designing a language — which is why programming-languages courses build interpreters in it. Its #lang datalog even re-hosts this roadmap’s Datalog topic as a Racket module.
History
A 1990s research line that became the standard teaching and language-prototyping platform.
Lineage
Racket began as PLT Scheme in 1995, led by Matthias Felleisen and Matthew Flatt at (then) Rice and Northeastern University, to teach programming and programming-language design; it was renamed Racket in 2010. Its IDE DrRacket (formerly DrScheme) has shipped with it from the start.
Implementation
Since Racket 8.0 (2020) the default implementation, Racket CS, compiles to Chez Scheme — a mature, fast Scheme implementation with a JIT (originally developed by R. Kent Dybvig). The project is maintained by the Racket community through racket-lang.org.
Stage
Mature and deliberately stable; the current release line is Racket 9.3.
Maturity
Racket has been a stable product for decades, with cross-platform graphical programming (Windows, macOS, Linux) since its beginning. The team’s own summary is blunt: mature and stable.
Hardening Tools
Racket pioneered higher-order software contracts and safe gradual typing: Typed Racket type-checks whole modules and interoperates with untyped code, and contracts guard module boundaries — both built to harden the very libraries that implement your DSLs.
Popularity & Usability
Dominant in programming-language education and language-design circles; smaller but healthy in industry niches.
Adoption
Program by Design (formerly TeachScheme!) is a high-school and college curriculum; Brown University’s programming-languages course implements interpreters in Racket, and the language-pragmatics field uses it constantly. The free book Beautiful Racket is the standard walk from zero to your first #lang.
Tooling
DrRacket gives steppers, a contract and macro stepper, and syntax-aware navigation; VS Code (Magic Racket), Emacs, and Vim integrations are first-party or well maintained. Packages install through Racket’s built-in package manager — no external toolchain.
Use Cases
Anywhere you would rather define a language than fight one.
New #lang Modules
Teaching languages, visualization DSLs, and domain notations: declare a #lang, give it rules, and modules written in it run through the normal Racket pipeline. Scribble, Racket’s own documentation DSL, is a production example — Racket documents itself in a Racket-defined language.
Macro-Based DSLs
Smaller moves: define new control constructs (a time-it form), embed a configuration or rule language as a library, or build conventional surface syntax with the parsing packages — Racket’s site demonstrates mapping arbitrary syntax to a parenthesized core that the macro system then compiles.
Performance
Macros cost nothing at run time, and Racket CS runs on a real JIT; be honest about where your DSL spends its time.
Compile-Time Work
Macro expansion happens before execution; the code you wrote as a language becomes ordinary Racket, then native code. Contracts and typed modules add predictable checks at module boundaries.
Runtime Profile
Racket CS performance is strong for interpreter workloads and prototypes; hot inner loops of a compiled DSL can be tightened with Typed Racket or the foreign-function interface to C. As with every language on this roadmap: profile before optimizing.
Example
One file, two ideas: an arithmetic expression treated as data (the roadmap’s AST as an S-expression) and a macro that extends the language itself. Run it with racket expressions.rkt.
expressions.rkt (commented)
#lang racket ; every file starts by choosing its language
(require racket/match) ; pattern matching over data, like OCaml’s
;; --- 1. code as data: a list IS the AST ---------------------------------
;; (plus 1 (times 2 3)) means 1 + 2 * 3
;; No parser: the evaluator walks the list, exactly like the
;; tree-walking evaluator on the Parsing & Trees page.
(define (eval-expr e)
(match e
[(? number? n) n] ; a number evaluates to itself
[(list 'plus a b) (+ (eval-expr a) (eval-expr b))]
[(list 'minus a b) (- (eval-expr a) (eval-expr b))]
[(list 'times a b) (* (eval-expr a) (eval-expr b))]))
(displayln (eval-expr '(plus 1 (times 2 3)))) ; prints 7
;; --- 2. a macro: teach the language a new construct ----------------------
(define-syntax-rule (twice body) (begin body body)) ; one rewrite rule
(twice (displayln "hi")) ; prints "hi" twice
;; --- 3. why this beats string parsing ------------------------------------
;; The reader turns source into lists; macro expansion rewrites code before
;; evaluation; eval-expr interprets. Together they ARE the compiler pipeline
;; from Phase 2, and each stage is just another Racket function.
How to Run
# download from racket-lang.org, then:
racket expressions.rkt
# 7
# hi
# hi
Notice what is missing: no tokenizer, no grammar file, no visitor. The evaluator pattern-matches the list, and the macro is the only place the language grew. This is language-oriented programming in miniature.
Learn More
Official sources and free materials; the full categorized catalog is on the References & Downloads page.
Official Docs & Downloads
- racket-lang.org — download and the full language ecosystem
- docs.racket-lang.org — the Guide, Reference, and macro documentation
- Macros — the core of extensibility
- The Racket Guide — official free documentation, including the Creating Languages chapter