# Racket (programming language)

> Source: https://aiwiki.ai/wiki/racket
> Updated: 2026-06-25
> Categories: Programming Languages
> From AI Wiki (https://aiwiki.ai), a free encyclopedia of artificial intelligence. Quote with attribution.

**Racket** is a general-purpose, multi-paradigm [programming language](/wiki/programming_language) in the [Lisp](/wiki/lisp) family and a direct descendant of [Scheme](/wiki/scheme). It is dynamically typed by default, supports first-class functions, [continuations](/wiki/continuation), and a hygienic macro system, and is built around an unusual feature for a Lisp: each source file declares its own language with a `#lang` line at the top, which lets users build and ship their own dialects on top of the same compiler and runtime. The project started on January 26, 1995 at [Rice University](/wiki/rice_university) under Matthias Felleisen as **PLT Scheme**, and was renamed Racket on June 7, 2010, the day version 5.0 shipped, to signal that the system had moved well beyond standard Scheme.[1][4][5] Its central design slogan, from the 2015 *Racket Manifesto*, is that "Racket is a programming language for creating new programming languages."[21]

Racket is best known for two things. The first is its long career as a teaching language behind the textbook *How to Design Programs* and the [DrRacket](/wiki/drracket) IDE used in introductory CS courses at Northeastern, Brown, Waterloo, and elsewhere.[7] The second is its role as a research vehicle for [programming language](/wiki/programming_language) design, where its emphasis on *language-oriented programming* has produced typed dialects, lazy dialects, solver-aided dialects, and dozens of domain-specific languages.[21] Today Racket is developed by a distributed group of researchers and contributors at Northeastern, Utah, Brown, Indiana, Waterloo, and elsewhere, and is released under the [MIT](/wiki/mit_license) and Apache 2.0 licenses.[3]

## At a glance

| Field | Value |
|---|---|
| Paradigms | Multi-paradigm: functional, imperative, object-oriented, logic, meta |
| Family | [Lisp](/wiki/lisp) / [Scheme](/wiki/scheme) |
| Typing discipline | Dynamic by default, optional static typing via [Typed Racket](/wiki/typed_racket) |
| First appeared | January 26, 1995 (as PLT Scheme) |
| Renamed Racket | June 7, 2010 (with version 5.0) |
| Designed by | Matthias Felleisen and the PLT group |
| Implementation | Racket CS (default since v8.0, built on [Chez Scheme](/wiki/chez_scheme)) |
| File extensions | `.rkt`, `.rktl`, `.scrbl` |
| License | MIT or Apache 2.0 (dual) |
| Website | racket-lang.org |

## Where did Racket come from?

### PLT Scheme (1995 to 2010)

The project traces to a single day. On January 25, 1995, on a flight, Cormac Flanagan asked Matthias Felleisen a question that became the founding prompt of the group: "If functional programming is that good, why is nobody using it?"[22] The next day, January 26, 1995, Felleisen and a core team (Shriram Krishnamurthi, Bruce Duba, Cormac Flanagan, and Matthew Flatt) met in Corky Cartwright's office at [Rice University](/wiki/rice_university) and committed to building a curriculum, a programming language, and supporting software to teach functional programming to novices.[22] Felleisen's stated goal at that meeting was to "build a curriculum, a programming language, and support software to use functional programming for teaching algebra."[22]

Within days Matthew Flatt put together the first virtual machine, MrEd, by stitching together libscheme, wxWidgets, and a few other free systems; the earliest documented release was version 0.7 on May 10, 1995.[22] From that base the group, including Flatt, Robby Findler, Shriram Krishnamurthi, and Cormac Flanagan, produced DrScheme, an editor and runtime aimed at students, alongside MzScheme, a command-line implementation with the same core. The umbrella name PLT Scheme came from the Programming Language Team, the research and pedagogy group Felleisen had organized around novice programmers.

The project grew steadily over the next fifteen years. Hygienic macros, the module system, contracts, and the language-level mechanism all arrived during the PLT Scheme era. By the late 2000s the system had drifted far enough from R5RS and R6RS Scheme, and added enough of its own features, that the Scheme name was starting to mislead users. The R6RS standard in particular pushed Scheme in a direction the PLT group did not want to follow, and there was no clean way to keep calling the system Scheme without inviting comparisons that did not really apply.

### When was Racket renamed, and why?

On June 7, 2010, PLT Scheme was renamed Racket, on the same day version 5.0 shipped.[1][5] The release notes for version 5.0 framed the change as a signal that the system had outgrown the Scheme label, and that future development would be done under a name that did not promise standards conformance with a language whose direction the project disagreed with. As Felleisen later put it in *Racket, Historically Speaking*: "By 2010, our dialect of Scheme had evolved so much that we renamed it to Racket."[4] DrScheme became DrRacket, MzScheme became Racket, and the PLT brand survived in package names and in the team itself.

After the rename, the focus shifted increasingly toward language-oriented programming and toward the macro system as a way of building entire languages, not just libraries. Typed Racket, which had been published in 2008 by Sam Tobin-Hochstadt and Matthias Felleisen, matured into a usable production dialect.[8] New dialects appeared, including Lazy Racket, Hackett, and Rosette, and the `#lang` mechanism became central to how Racket code was structured.

### The move to Chez Scheme

The original Racket virtual machine, retroactively called Racket BC ("before Chez" or "bytecode"), was a custom JIT-based implementation written largely in C. Starting around 2017 the team, led by Matthew Flatt, began rewriting the runtime on top of [Chez Scheme](/wiki/chez_scheme), Kent Dybvig's high-performance Scheme compiler. Cisco had open-sourced Chez Scheme in 2016, which made the move possible.

The rewrite replaced about 200,000 lines of C code with around 150,000 lines of Scheme and Racket code.[12] The new implementation, called Racket CS, became the default in Racket 8.0 on February 13, 2021.[12] Racket BC remained available through a separate installer, mainly to support older code that depended on its FFI quirks. Racket CS ships with better generational and parallel garbage collection, faster startup, and a smaller maintenance burden, since the compiler is written in the same family of languages it compiles.[12]

## What does Racket's language design look like?

Racket is a Lisp-1, which means functions and values share a single namespace. This is the same convention as [Scheme](/wiki/scheme) and [Clojure](/wiki/clojure) and the opposite of [Common Lisp](/wiki/common_lisp), which keeps separate namespaces for functions and ordinary variables. The Lisp-1 choice makes higher-order programming smoother because the same name `f` can refer to a function value without `funcall` or `#'` ceremony.

Like every Lisp, Racket is [homoiconic](/wiki/homoiconicity): programs are written as nested S-expressions, and the same nested-list structure is what macros operate on. A short example:

```racket
#lang racket

(define (fact n)
  (if (= n 0)
      1
      (* n (fact (- n 1)))))

(fact 10) ; 3628800
```

The `#lang racket` line at the top is the part that does not look like ordinary Scheme. It declares which language to read the rest of the file in. `racket` is the kitchen-sink dialect with the full standard library; `racket/base` is a smaller subset; `typed/racket` adds static types; `lazy` makes evaluation lazy; `scribble/base` turns the file into a documentation source. Each `#lang` is itself a normal Racket module that can be installed via the package system, which means new languages are first-class users of the same tooling as ordinary code.

### Macros and language-oriented programming

Racket's macro system extends Scheme's `syntax-rules` and `syntax-case` with `syntax-parse`, a pattern-matching language for syntax that includes integrated error messages and reusable syntax classes. Macros are hygienic by default, meaning identifiers introduced by a macro do not accidentally capture or conflict with identifiers in the surrounding code. This is the same property [Scheme](/wiki/scheme) made standard with `syntax-rules` in 1986, but Racket extends it with control over hygiene when you actually need to break it.

The deeper claim Racket makes is that macros are not just for adding little features to an existing language. They are for building entire new languages. The 2015 *Racket Manifesto* states the thesis directly: "Racket is a programming language for creating new programming languages, so that programmers can tailor a language to fit their problem."[21] In practice, a `#lang` is a module that exports a reader and a set of macros, and the result is that the file under it gets a brand-new surface syntax and semantics. Racket has been used this way to build educational sublanguages (the various Beginning, Intermediate, and Advanced Student Languages used by *How to Design Programs*), typed dialects, lazy dialects, query languages, build systems, slideware, and book-publishing systems.[7][19] Matthew Butterick's book *Beautiful Racket* is a long worked example of building several small languages from scratch using these tools.[15]

A tiny taste of a macro:

```racket
#lang racket

(define-syntax-rule (unless test body ...)
  (if test (void) (begin body ...)))

(unless (> 1 2)
  (displayln "one is not greater than two"))
```

`unless` is not a primitive in Racket; this defines it as a one-line macro that expands to an `if`.

### Contracts

Racket also ships with a contract system, originally designed by Findler and Felleisen, that lets you attach precondition and postcondition checks to functions and modules.[18] Contracts are first-class values and can be combined like other values. When a contract fails, the system blames a specific party (the function or its caller) rather than just printing a stack trace.[18] The contract work fed directly into Typed Racket, since the boundary between typed and untyped modules is implemented as automatically generated contracts.[8]

## What is Racket's type system?

By default Racket is dynamically typed, with the usual Lisp behavior: any value can be stored in any variable, and type errors show up at runtime. This is the same model as [Scheme](/wiki/scheme), [Clojure](/wiki/clojure), and other dynamic Lisps.

For code that wants static types, the standard option is **Typed Racket**, a typed dialect that lives at `typed/racket`. Typed Racket was introduced by Sam Tobin-Hochstadt and Matthias Felleisen in their 2008 POPL paper *The Design and Implementation of Typed Scheme*, and it is one of the better-known industrial-strength gradual typing systems.[8] It is designed to be sound across the boundary between typed and untyped modules, with values passed between the two worlds wrapped in dynamically checked contracts.

Typed Racket includes recursive union types, parametric polymorphism, subtyping, and a feature called occurrence typing, which refines a value's type within a branch based on a type predicate. For example:

```racket
#lang typed/racket

(: greet (-> (U String #f) String))
(define (greet name)
  (if (string? name)
      (string-append "hello, " name)
      "hello, stranger"))
```

Inside the `if` branch, `name` is narrowed from `(U String #f)` to `String`, so `string-append` typechecks without an explicit cast. The follow-up paper *Logical Types for Untyped Languages* (Tobin-Hochstadt and Felleisen, 2010) gave the formal account of how this works.[9]

A decade after the original paper, the same authors published *Migratory Typing: Ten Years Later* (2017), reflecting on what worked and what did not.[10] One recurring finding was that soundness comes at a real cost when typed and untyped code mix heavily, since contract checks at module boundaries can dominate runtime; *Is Sound Gradual Typing Dead?* (Takikawa et al., POPL 2016) measured this in detail.[11] Subsequent Typed Racket work has focused on reducing those overheads.

## Implementation

Racket today has two implementations that share most of the same surface language:

| Implementation | Status | Notes |
|---|---|---|
| Racket CS | Default since 8.0 (February 13, 2021) | Built on [Chez Scheme](/wiki/chez_scheme); faster, parallel garbage collection, easier to maintain |
| Racket BC | Legacy, available via separate installer | Original C-based VM with custom JIT; kept for compatibility |

Both implementations compile through the same expander, which is itself written in Racket, so a `#lang` defined in one works in the other.[12] The expander, written by Matthew Flatt and known as the "new" or bootstrapped expander, is one of the larger pieces of Racket-in-Racket and the step that made the Chez migration possible: once the expander was self-hosting, the choice of underlying runtime became swappable.

## DrRacket

[DrRacket](/wiki/drracket), formerly DrScheme, is the official IDE. It is itself a Racket program. The interface has two panes: a definitions window for editing source, and an interactions window that doubles as a REPL. The IDE understands the `#lang` line of the open file and switches its behavior accordingly: hitting Run on a `#lang typed/racket` file gets you the Typed Racket type checker; opening a Beginning Student Language file restricts the available primitives and syntax to the subset matching a given chapter of *How to Design Programs*.[7]

Features that are unusual for a beginner-focused IDE include a stepper that shows substitution-based reduction one step at a time (used heavily in introductory courses), a graphical syntax-error highlighter that draws arrows from binding to use, integrated check-syntax for tracking variable scope, an algebraic stepper, and tight integration with the macro expander so that you can step through a macro expansion the way you might step through a function call. DrRacket also doubles as a research IDE for the language-design work the PLT group does, since modifications to the expander and reader are visible inside the same environment that students use.

## What is Racket used for in teaching?

A significant fraction of Racket's user base touches the language through a CS course or a curriculum, not through industry. Two efforts in particular are worth singling out.

*How to Design Programs* (HtDP), by Matthias Felleisen, Robert Bruce Findler, Matthew Flatt, and Shriram Krishnamurthi, was first published by [MIT Press](/wiki/mit_press) in 2001, with a second edition in 2018 that is freely available online.[7] The book teaches a systematic approach called the *design recipe*, a six-step process from data definitions through templates to function bodies and tests. It does not use the full Racket language. Instead it uses a sequence of teaching languages (Beginning Student, Beginning Student with List Abbreviations, Intermediate Student, Intermediate with Lambda, Advanced Student) that grow in expressive power as the student progresses. The teaching languages are themselves built using the `#lang` mechanism. HtDP underlies introductory courses at Northeastern, Brown, the University of Waterloo, the University of British Columbia, and other places.[6]

The **Bootstrap** curriculum, started by Emmanuel Schanzer in 2005 with Kathi Fisler at WPI and Shriram Krishnamurthi at Brown, takes a similar approach but pushes it down into middle and high schools.[16] Bootstrap:Algebra teaches students to write a small video game while simultaneously covering linear functions, function composition, the Pythagorean theorem, piecewise functions, and other topics from a standard algebra curriculum.[17] The programs are written in a teaching subset of Racket, and the curriculum has been used in over 150 schools in the United States.[16]

## Ecosystem

The Racket ecosystem is small compared to mainstream languages, but it is reasonably complete. The package manager is invoked through `raco`, which is the umbrella command-line tool for everything that is not the language proper:

| Command | Purpose |
|---|---|
| `raco pkg install`/`update`/`remove` | Package management |
| `raco make` | Ahead-of-time bytecode compilation |
| `raco exe` | Build a standalone executable |
| `raco doc` | Open the local documentation |
| `raco test` | Run a test suite |
| `raco scribble` | Build documentation from Scribble sources |

Packages live in a central catalog at `pkgs.racket-lang.org`, but a package source can also be a Git repository or a zip file. There is no version pinning beyond what a Git ref or a release file gives you, and the catalog is more of a name-to-source map than a content host.

A non-exhaustive list of well-known Racket projects:

| Project | Author(s) | Description |
|---|---|---|
| Typed Racket | Tobin-Hochstadt, Felleisen, others | Statically typed dialect |
| Rosette | Emina Torlak, Rastislav Bodik | Solver-aided language for synthesis and verification, built on Z3 |
| Hackett | Alexis King | Haskell-like language with Racket macros |
| Pollen | Matthew Butterick | Publishing system used to write *Practical Typography* and *Beautiful Racket* |
| Frog | Greg Hendershott | Static blog generator |
| Scribble | PLT | Documentation language used for the Racket reference and HtDP itself |
| Lazy Racket | PLT | Call-by-need variant |
| FrTime | PLT | Functional reactive variant |

Scribble deserves a separate mention. It is the documentation language that the Racket reference, the Racket guide, and a long list of third-party manuals are written in. Pollen is in turn built on Scribble, which is the kind of layered DSL stack that the `#lang` system is designed to encourage.

## How does Racket differ from other Lisps?

Racket sits in the same family as several other Lisps, and the differences are easier to see side by side.

| Feature | Racket | [Scheme](/wiki/scheme) | [Common Lisp](/wiki/common_lisp) | [Clojure](/wiki/clojure) |
|---|---|---|---|---|
| Namespaces | Lisp-1 | Lisp-1 | Lisp-2 | Lisp-1 |
| Standard size | Large, batteries-included | Small, minimalist | Large, ANSI standard | Medium, hosted on JVM |
| Macro hygiene | Hygienic, with `syntax-parse` | Hygienic since R5RS | `defmacro`, not hygienic by default | Mostly hygienic via gensym/`#'` |
| Typing | Dynamic plus optional static (Typed Racket) | Dynamic | Dynamic, with optional declarations | Dynamic, plus core.typed and Spec |
| Concurrency | Threads, places, futures | Implementation-defined | Implementation-defined | STM-influenced reference types |
| Host platform | Native (Chez) or BC | Many | Many | JVM, JS, .NET via ports |
| Distinctive feature | `#lang` and language-oriented programming | Minimalism, continuations | Macros and CLOS object system | JVM interop, persistent data structures |

If you already know Scheme, most of Racket will feel familiar, with two big additions: the `#lang` mechanism and the much larger standard library. If you come from Common Lisp, the absence of CLOS in the same form will feel odd, although Racket has its own object system. If you come from Clojure, the static-typing story is very different (Typed Racket is more sound-by-construction than core.typed) and the host story is the inverse: Racket runs on its own runtime rather than on the JVM.

## Is Racket relevant to AI and PL research?

Racket has been a workhorse for [programming language](/wiki/programming_language) research, especially around macros, gradual typing, and contracts. The volume of POPL, ICFP, and PLDI papers using Racket as either object of study or implementation vehicle is large, and several techniques that are now common in mainstream languages, like sound gradual typing and structural contracts, were prototyped in Racket first.[10][11]

The relevance to AI is mostly indirect, through two channels. The first is *program synthesis* and *formal verification*, both of which connect to the idea of generating or checking programs against specifications, which is also what large language model code assistants try to do, just by very different means. **Rosette**, designed by Emina Torlak and Rastislav Bodik and described in the 2013 Onward! paper *Growing Solver-Aided Languages with Rosette*, is a Racket-based language that compiles programs to logical constraints solved by SMT solvers like Z3.[13][14] Rosette has been used to build verifiers and synthesizers for new languages by writing an interpreter and letting the solver do the heavy lifting, which complements LLM-based program generation rather than competing with it. **Sketch**, designed by Armando Solar-Lezama, is the original syntax-guided synthesis system; while Sketch itself is not in Racket, the synthesis-by-sketching idea has been re-implemented and extended in Rosette.

The second channel is education. A non-trivial fraction of [programming language](/wiki/programming_language) researchers, including some who work on formal methods, type theory, and synthesis at AI-adjacent labs, learned to think about programs through *How to Design Programs*.[7] The design-recipe approach, the emphasis on data definitions and templates, and the use of contracts to specify behavior are all habits that show up in research code regardless of the language it ends up in.

This influence is real but easy to overstate. Racket is not a meaningful target for industrial machine-learning workloads, has no GPU story to speak of, and is not on the shortlist of languages that LLM code assistants are tuned for. Its place in an AI Wiki is as a notable Lisp dialect with a serious teaching tradition and a research community that overlaps with the formal-methods side of computer science.

## Notable users and projects

Racket has not been a fixture of mainstream commercial software, but it has been used in several visible places. In academia, Racket is used in production in courses at Northeastern (Felleisen's group), Brown (Krishnamurthi), the University of Utah (Flatt), Indiana University (Tobin-Hochstadt), the University of Waterloo, and Worcester Polytechnic Institute (Fisler), among others.[6] Pollen, the publishing system, has been used to produce several professionally typeset books, including Matthew Butterick's *Practical Typography* and *Typography for Lawyers*.[15] The Racket reference manual itself is one of the longest documents written in Scribble.

## ELI5: What is Racket?

Imagine a box of LEGO that does not just let you build models, but also lets you invent brand-new kinds of LEGO bricks and then build with those. Racket is a programming language that is great at making other little programming languages. You can write a normal program in it, like one that prints the numbers 1 to 10. But you can also write your own mini-language for, say, drawing pictures or making a game, and then write programs in that. That is why teachers love it (students learn step by step with simpler versions of the language) and why language researchers love it (they can try out new language ideas quickly).

## See also

- [Lisp](/wiki/lisp)
- [Scheme](/wiki/scheme)
- [Common Lisp](/wiki/common_lisp)
- [Clojure](/wiki/clojure)
- [Homoiconicity](/wiki/homoiconicity)
- [Functional programming](/wiki/functional_programming)
- [Typed Racket](/wiki/typed_racket)
- [Gradual typing](/wiki/gradual_typing)
- [Chez Scheme](/wiki/chez_scheme)
- [DrRacket](/wiki/drracket)
- [Matthias Felleisen](/wiki/matthias_felleisen)

## References

1. Racket project. "Racket Documentation." https://docs.racket-lang.org/
2. Racket project. "Download Racket." https://download.racket-lang.org/
3. Racket project. "Software License." https://download.racket-lang.org/license.html
4. Felleisen, Matthias. "Racket, Historically Speaking." https://felleisen.org/matthias/manifesto/Racket__Historically_Speaking.html
5. Wikipedia. "Racket (programming language)." https://en.wikipedia.org/wiki/Racket_(programming_language)
6. Wikipedia. "How to Design Programs." https://en.wikipedia.org/wiki/How_to_Design_Programs
7. Felleisen, M., Findler, R. B., Flatt, M., Krishnamurthi, S. *How to Design Programs*, 2nd ed., MIT Press, 2018. https://htdp.org/
8. Tobin-Hochstadt, S. and Felleisen, M. "The Design and Implementation of Typed Scheme." POPL 2008. https://www2.ccs.neu.edu/racket/pubs/dissertation-tobin-hochstadt.pdf
9. Tobin-Hochstadt, S. and Felleisen, M. "Logical Types for Untyped Languages." ICFP 2010. https://www2.ccs.neu.edu/racket/pubs/icfp10-thf.pdf
10. Tobin-Hochstadt, S., et al. "Migratory Typing: Ten Years Later." SNAPL 2017. https://www2.ccs.neu.edu/racket/pubs/typed-racket.pdf
11. Takikawa, A., et al. "Is Sound Gradual Typing Dead?" POPL 2016. https://www2.ccs.neu.edu/racket/pubs/popl16-tfgnvf.pdf
12. Racket Blog. "Racket Compiler and Runtime Status: January 2021." https://blog.racket-lang.org/2021/01/racket-status.html
13. Torlak, E. and Bodik, R. "Growing Solver-Aided Languages with Rosette." Onward! 2013. https://homes.cs.washington.edu/~bodik/ucb/Files/2013/onward13.pdf
14. Rosette project. "Rosette: About." https://emina.github.io/rosette/
15. Butterick, M. *Beautiful Racket*. https://beautifulracket.com/
16. Bootstrap project. https://www.bootstrapworld.org/
17. Wikipedia. "Bootstrap curriculum." https://en.wikipedia.org/wiki/Bootstrap_curriculum
18. Findler, R. B. and Felleisen, M. "Contracts for higher-order functions." ICFP 2002.
19. Flatt, M. "Creating Languages in Racket." *ACM Queue*, 2011. https://queue.acm.org/detail.cfm?id=2068896
20. Racket GitHub repository. https://github.com/racket/racket
21. Felleisen, M., Findler, R. B., Flatt, M., Krishnamurthi, S., Barzilay, E., McCarthy, J., Tobin-Hochstadt, S. "The Racket Manifesto." SNAPL 2015, LIPIcs Vol. 32, pp. 113-128. https://www2.ccs.neu.edu/racket/pubs/manifesto.pdf
22. Racket Blog. "Racket is 25." May 2020. https://blog.racket-lang.org/2020/05/racket-is-25.html

