Racket 编程入门

第 1 部分 · 起点:编程与计算的本质

导读——为什么学、怎么读

在打开任何一篇具体教程之前,先建立 Racket 的全局认知:它究竟是什么、为什么值得花时间学,以及本系列 40 篇该怎么读。

你点开 Racket,大概最先被满屏的括号劝退过;再往里走,S-表达式、宏、延续、λ 演算、CPS……每一个都像一道门,门后还有门。新手最普遍的困境不是某个知识点难,而是不知道地图长什么样,每一步都像在黑屋里摸索。这篇导论就是那张地图。

Racket 不是“又一门语言”,是造语言的语言

大多数编程语言是给你用的——语法写死、功能定好,你用它写程序。Racket 不太一样:它是一个用来造编程语言的平台。官方自己说,Racket 是“一门用来创造编程语言的编程语言”(language-oriented programming)。

这是它 Lisp 血统的延续。Lisp 家族用 S-表达式把“代码”和“数据”统一成同一种结构——你的程序本身就是一棵可以读、可以改、可以生成的列表。Racket 在这之上更进一步:文件第一行 #lang 不只是声明“我用 Racket 写”,它是在挑一门语言——Racket 自带 typed/racket(带类型)、scribble(文档语言)、racket/gui,你还能自己写一个 #lang。别的语言语法是规定好的,Racket 的语法是可造的。

打个比方:普通语言像成品玩具,Racket 像乐高——乐高的乐趣不在拼出某一个成品,而在你随时能拆开、按自己的想法重拼。

它还有一个常被忽略的身份:出身是教学语言。Racket 的前身是 PLT Scheme,为《How to Design Programs》这门经典入门课而生,配套的 DrRacket 也是为教学设计的。所以它对新手的态度是认真的——不是为了好用,是为了让人学懂。

为什么值得学 Racket

学一门语言要花时间,得有足够的回报。Racket 至少给你四样别处不太好凑齐的东西。

三范式,一门语言里都齐了。 函数式、命令式、面向对象——通常你得分别去学 Haskell、C、Java 才能体会。Racket 三者都原生支持,而且不是凑数:它是一门正经的函数式语言,也能写命令式的 set! 和循环,还有一套完整的 class 系统。在一个地方看清三种范式各自的长处和短处,这是 Racket 独有的便利。

语言不够用,就自己造。 这是别的语言给不了的能力。宏让你扩展语法、DSL 让你为某个领域定制一门小语言、#lang 让你定义全新的语言。当你在别的语言里抱怨“要是有个这样的语法就好了”,在 Racket 里你能直接把它造出来。本系列最后一板块会带你亲手造一个迷你 DSL。

REPL,边跑边学。 Racket 配套的 DrRacket 有两扇窗:上面写代码,下面是交互区(REPL),敲一行立刻看到结果。学新东西最快的方式不是读完一章再敲,是边读边敲、立刻验证。这种学法,Racket 给了最好的环境。

理解编程语言本质的最佳入口。 宏、延续(continuation)、λ 演算——这些是编程语言理论里最深刻、也最常被讲得云里雾里的概念。Racket 把它们做成了可以上手把玩的东西。学完 Racket 再看任何一门语言,你都会多一层“它为什么这么设计”的理解。

代价当然有:括号劝退期、就业市场不如主流语言大、生态规模有限。但作为理解编程本质的训练,Racket 的性价比极高。

本系列的阅读地图

本系列 40 篇,分五个板块,每个板块回答一个递进的问题。

racket-series-map

板块一 · 基础回答“用 Racket 写点什么,最少要知道什么”。从装好环境、认出 DrRacket 两扇窗开始,过数据类型、列表、结构体,到函数与闭包、S-表达式。读完这一板块,你能在 REPL 里随手算账、处理数据,看懂 Racket 代码的基本形状。

板块二 · 函数式回答“不动用状态,怎么完成计算”。讲高阶函数(map/filter/fold)、递归、函数的组合与管道,一路到 λ 演算和一个手写的迷你解释器。函数式是 Racket 的核心范式,也是理解它一切设计的起点。

板块三 · 命令式回答“状态随时间怎么改变”。讲异常处理、资源的自动管理(Custodian),并用一个红绿灯状态机做实战——这是命令式编程最经典的形态。

板块四 · 面向对象与 GUI回答“对象怎么组织、界面怎么搭”。从 Racket 的 class 系统开始,写出第一个 GUI 窗口,再到控件、自定义绘制、声明式 GUI、不卡顿的后台任务。GUI 是面向对象最自然的练兵场。

板块五 · 计算模型与语言设计回答“语言本身是怎么造出来的”。宏、延续、generator、模块机制,最后亲手造一个迷你 DSL。这是 Racket 最有意思、也最能体现“造语言的语言”的地方。

阅读顺序上,建议按板块一到五顺读——每个板块都建立在前面的概念上。但你也完全可以按兴趣跳读:只想写 GUI,就直接跳到板块四,遇到不懂的再回看。每篇都尽量自包含。

怎么读每一篇

本系列的每一篇都遵循统一结构,认出它就不再迷路:

  • > 开篇一句话总结 + 提问 hook——告诉你这篇讲什么、为什么值得看
  • 洞察式的 ## 标题——不是“第一步/第二步”,而是每节的判断
  • 可运行的代码——每段都能在 DrRacket 里跑,注释里直接给结果
  • 关键结论加粗——一眼能抓到重点
  • 标了“项目”的章节带你动手实战,从零写一个能跑的东西

第一次读,建议在交互区里把每段代码都敲一遍——这是学 Racket 最有效的方式。哪篇看不懂,往往是某篇前置概念没熟,回看一眼板块地图就能定位。

先决知识

零基础。你不需要会别的语言,也不需要懂函数式或 Lisp。

唯一的准备工作是装好 Racket 和 DrRacket——这一步在系列第一篇《Racket 编程入门 4:装好 Racket,认出 DrRacket 的两扇窗》里有完整的手把手步骤。装完它,回到这篇导论,按板块一开始读就行。

带着这张地图,我们出发。下一篇,《装好 Racket,认出 DrRacket 的两扇窗》。