A Friendly Introduction to Racket

A Friendly Introduction to Racket

A Friendly Introduction to Racket Racket 友好入门指南

11 Aug, 2026 2026年8月11日

“Lisp is worth learning for the profound enlightenment experience you will have when you finally get it.” — Eric S. Raymond “Lisp 值得学习,因为当你最终领悟它时,你会获得一种深刻的启迪。”—— Eric S. Raymond

Welcome. Today you’ll learn a language from one of programming’s oldest and most unusual families. A language where code is data, where parentheses are pure structure, and where programs can write programs. By the end of this tutorial, you’ll have written your own syntax. 欢迎。今天,你将学习一种来自编程界最古老、最独特家族之一的语言。这是一种代码即数据、括号即纯粹结构、程序可以编写程序的语言。在本教程结束时,你将亲手编写出属于自己的语法。

A bit of history

历史简述

Lisp was born in 1958, invented by John McCarthy at MIT. For context: it’s the second-oldest high-level language still in use (only Fortran, from 1957, beats it by a year). Python arrived in 1991. JavaScript in 1995. Lisp predates them by more than 30 years and several ideas we now consider “modern” were born there: Lisp 诞生于 1958 年,由麻省理工学院的约翰·麦卡锡(John McCarthy)发明。作为背景:它是目前仍在使用的第二古老的高级语言(仅比 1957 年的 Fortran 晚一年)。Python 出现于 1991 年,JavaScript 出现于 1995 年。Lisp 比它们早了 30 多年,而我们现在认为“现代”的许多概念都源于此:

  • Garbage collection — invented for Lisp.
  • 垃圾回收 —— 为 Lisp 而发明。
  • First-class functions — passing functions as arguments, now standard everywhere.
  • 一等函数 —— 将函数作为参数传递,现在已是各处的标准。
  • The REPL — the interactive read-eval-print loop that Python, Node, and Julia all have today started in Lisp.
  • REPL —— Python、Node 和 Julia 今天所拥有的交互式读取-求值-输出循环,最初始于 Lisp。
  • Conditionals as expressions — the if that returns a value.
  • 条件表达式 —— 即返回值的 if 语句。
  • Homoiconicity — code is a data structure of the language itself. This is the big one. We’ll come back to it at the end.
  • 同像性(Homoiconicity) —— 代码即语言本身的数据结构。这是最重要的一点,我们最后会回到这里。

For decades, Lisp was the language of artificial intelligence. In the 70s and 80s there were physical computers designed to run Lisp directly: the Lisp Machines built by Symbolics and LMI. Then came the “AI winter,” funding dried up, and Lisp went from star to cult language. But interesting ideas don’t die they mutate, that’s part of the beauty of the lisps. 几十年来,Lisp 一直是人工智能的语言。在 70 和 80 年代,甚至有专门为运行 Lisp 而设计的物理计算机:由 Symbolics 和 LMI 公司制造的“Lisp 机器”。随后“AI 寒冬”来临,资金枯竭,Lisp 从明星语言变成了小众语言。但有趣的创意不会消亡,它们只会演变,这也是 Lisp 家族魅力的一部分。

From Lisp to Scheme to Racket

从 Lisp 到 Scheme 再到 Racket

In 1975, Gerald Sussman and Guy Steele created Scheme: a minimalist, elegant, almost mathematical Lisp. Scheme became academia’s favorite language for teaching programming (the legendary book SICP: Structure and Interpretation of Computer Programs is written in Scheme). In 1995, Matthias Felleisen’s group created PLT Scheme, a Scheme designed for education and programming language research. In 2010 it was renamed Racket, and today it’s much more than a Scheme: it’s a language for building languages. Its unofficial motto is language-oriented programming: if your problem needs its own language, Racket lets you build one in an afternoon. 1975 年,Gerald Sussman 和 Guy Steele 创建了 Scheme:一种极简、优雅、近乎数学化的 Lisp。Scheme 成为了学术界教授编程的首选语言(传奇书籍《计算机程序的构造和解释》(SICP) 就是用 Scheme 编写的)。1995 年,Matthias Felleisen 的团队创建了 PLT Scheme,这是一种专为教育和编程语言研究而设计的 Scheme。2010 年,它更名为 Racket,如今它已不仅仅是 Scheme:它是一个构建语言的语言。其非官方座右铭是“面向语言的编程”:如果你的问题需要一种专门的语言,Racket 让你可以在一个下午内构建出来。

YearEvent
1958McCarthy invents Lisp at MIT
1975Sussman and Steele create Scheme
1984Common Lisp is standardized
1995PLT Scheme (now Racket) is born
2007Clojure is born (Lisp on the JVM)
2010PLT Scheme is renamed Racket
年份事件
1958麦卡锡在 MIT 发明 Lisp
1975Sussman 和 Steele 创建 Scheme
1984Common Lisp 标准化
1995PLT Scheme(现为 Racket)诞生
2007Clojure 诞生(运行在 JVM 上的 Lisp)
2010PLT Scheme 更名为 Racket

Who uses Lisp today?

谁在今天使用 Lisp?

More people than you might think: Clojure runs in production at banks, airlines, and startups (Nubank, the largest digital bank in Latin America, runs on Clojure). Common Lisp (with the SBCL compiler) is still alive in expert systems, flight planning (ITA Software, acquired by Google, powered Google Flights), and scientific computing. Emacs Lisp — millions of people run Lisp every day without knowing it, because their editor is a Lisp interpreter. Guile/Guix — an entire Linux distribution configured 100% in Scheme. 使用的人比你想象的要多:Clojure 在银行、航空公司和初创公司中用于生产环境(拉丁美洲最大的数字银行 Nubank 就运行在 Clojure 上)。Common Lisp(配合 SBCL 编译器)依然活跃在专家系统、飞行规划(被谷歌收购的 ITA Software,其技术支撑了 Google Flights)和科学计算领域。Emacs Lisp —— 数百万人每天都在运行 Lisp 而不自知,因为他们的编辑器就是一个 Lisp 解释器。Guile/Guix —— 整个 Linux 发行版 100% 使用 Scheme 进行配置。

Racket has its own annual conference (RacketCon), an active academic and artistic community, and is used for language research, formal verification (Rosette), typography and publishing (Pollen), and education around the world. And new Lisps keep appearing: Fennel (a Lisp that compiles to Lua, popular for games), Janet, Hy (a Lisp on top of Python)… Racket 拥有自己的年度会议 (RacketCon),拥有活跃的学术和艺术社区,并被用于语言研究、形式化验证 (Rosette)、排版与出版 (Pollen) 以及全球教育。新的 Lisp 语言也在不断涌现:Fennel(一种编译为 Lua 的 Lisp,在游戏开发中很流行)、Janet、Hy(运行在 Python 之上的 Lisp)……

Easter egg for TADC fans: In The Amazing Digital Circus (episode 8, “hjsakldfhl”), when Kinger opens the terminal to try to reset Caine, you can see that Caine (a creative AI built in 1996) is programmed in Lisp. The file is literally named Caine-core.lisp. 给 TADC 粉丝的彩蛋:在《神奇数字马戏团》(第 8 集 “hjsakldfhl”)中,当 Kinger 打开终端试图重置 Caine 时,你可以看到 Caine(一个 1996 年构建的创意 AI)是用 Lisp 编写的。该文件直接命名为 Caine-core.lisp。

Installation (5 minutes)

安装(5 分钟)

  1. Go to https://racket-lang.org

  2. Download the installer for your system (Linux, macOS, Windows).

  3. Open DrRacket, the environment that comes included.

  4. DrRacket has two areas: at the top you write your definitions (your program), and at the bottom you have the REPL for live experimentation.

  5. On the first line of the definitions area, write: #lang racket

  6. That line tells Racket which language you’re using (remember: Racket is a language factory, so you have to pick one).

  7. If you prefer the terminal: the racket command gives you a REPL, and raco is the package manager and tooling command.

  8. 前往 https://racket-lang.org

  9. 下载适用于你系统的安装程序(Linux、macOS、Windows)。

  10. 打开随附的开发环境 DrRacket。

  11. DrRacket 有两个区域:顶部用于编写定义(你的程序),底部是用于实时实验的 REPL。

  12. 在定义区域的第一行,输入:#lang racket

  13. 这一行告诉 Racket 你正在使用哪种语言(记住:Racket 是一个语言工厂,所以你必须选择一种)。

  14. 如果你更喜欢终端:racket 命令会启动一个 REPL,而 raco 是包管理器和工具命令。

First contact: everything is an expression

初次接触:一切皆表达式

In the REPL, try: 在 REPL 中尝试:

> (+ 1 2)
3
> (* 3 (+ 2 2))
12
> (string-append "hello " "world")
"hello world"

The rule of Lisp fits in one line: Everything is (operator argument1 argument2 …). Always. No exceptions. There’s no operator precedence to memorize, no special syntax for anything. (+ 1 2) adds. (if ...) decides. (define ...) names. The parentheses that look intimidating at first are actually the complete absence of arbitrary rules. After a week, you stop seeing them. Lisp 的规则只有一行:一切皆为 (运算符 参数1 参数2 …)。 永远如此,没有例外。没有需要记忆的运算符优先级,也没有任何特殊语法。(+ 1 2) 执行加法,(if ...) 执行判断,(define ...) 执行命名。起初看起来令人生畏的括号,实际上代表了对任意规则的彻底摒弃。一周后,你就会对它们视而不见。

Definitions and functions

定义与函数

#lang racket
(define pi-approx 3.14159)
(define (circle-area r) (* pi-approx r r))
(circle-area 2) ; => 12.56636

define with a name creates a constant. define with (name arguments...) creates a function. Comments start with ;. Anonymous functions use lambda (yes, that lambda — Church’s lambda calculus from the 1930s is the theoretical grandparent of all this): 使用 define 加名称可以创建常量。使用 define(名称 参数...) 可以创建函数。注释以 ; 开头。匿名函数使用 lambda(没错,就是那个 lambda —— 1930 年代丘奇的 lambda 演算正是这一切的理论鼻祖):

(lambda (x) (* x x)) ; a function with no name
((lambda (x) (* x x)) 5) ; => 25, applied directly

Lists: the heart of Lisp

列表:Lisp 的核心

Lisp stands for LISt Processing. Lists are the fundamental structure: Lisp 代表 LISt Processing(列表处理)。列表是其基础结构:

(list 1 2 3) ; => '(1 2 3)
'(1 2 3)     ; the same thing, "quoted"
(first '(1 2 3)) ; => 1
(rest '(1 2 3))  ; => '(2 3)
(cons 0 '(1 2 3)) ; => '(0 1 2 3)
(length '(a b c)) ; => 3

Notice the quote mark '. It tells Racket: don’t evaluate this, it’s data. Hold onto that detail — it’s the door to the final trick. 注意那个引号 '。它告诉 Racket:不要对它求值,这只是数据。记住这个细节 —— 这是通往终极技巧的大门。

Higher-order functions

高阶函数

This is where Racket shines. Passing functions to other functions is the most natural thing in the world: 这是 Racket 大放异彩的地方。将函数传递给其他函数是再自然不过的事情:

(map (lambda (x) (* x x)) '(1 2 3 4 5)) ; => '(1 4 9 16 25)
(filter even? '(1 2 3 4 5 6)) ; => '(2 4 6)
(foldl + 0 '(1 2 3 4 5)) ; => 15

map transforms, filter selects, foldl accumulates. With those three functions… map 用于转换,filter 用于筛选,foldl 用于累加。有了这三个函数……