友好的Racket入门指南

Hacker News Top 工具

摘要

Racket友好入门,一种用于语言导向编程的Lisp方言,讲述其从Lisp起源到现代教育与研究应用的发展历程。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/08/22 16:32

# Racket 语言友好入门指南 来源:https://geometridae.bearblog.dev/a-friendly-introduction-to-racket/ *2026年8月11日* steal-your-face-plt > “Lisp 值得学习,因为当你最终理解它时,将获得深刻的启蒙体验。” —— Eric S. Raymond 欢迎!今天你将学习一门来自编程史上最古老、最独特的语族中的语言。这门语言中代码即数据,括号是纯粹的结构,程序可以编写程序。在本教程结束时,你将能编写自己的语法。 --- ## 简要历史 Lisp 诞生于**1958年**,由麻省理工学院的 John McCarthy 发明。作为参考:它是仍在使用的第二古老的高级语言(仅比1957年的 Fortran 晚一年)。Python 在1991年诞生,JavaScript 在1995年出现。Lisp 比它们早30多年,我们现在认为"现代"的许多理念都源于此: - **垃圾回收机制**——*专门为*Lisp 发明。 - **一等函数**——将函数作为参数传递,如今已成标准。 - **REPL**(读取-求值-打印循环)——Python、Node.js 和 Julia 都有的交互式环境,就起源于 Lisp。 - **条件表达式作为值**——能返回值的`if`语句。 - **同像性**——代码*就是*语言本身的数据结构。这是关键特性。我们将在文末详细讨论。 数十年来,Lisp *一直是*人工智能领域的首选语言。在70和80年代,甚至有专门设计来直接运行 Lisp 的实体计算机:由 Symbolics 和 LMI 公司制造的**Lisp 机器**。随后"AI寒冬"来临,资金枯竭,Lisp 从明星语言变为小众语言。 但有趣的思想不会消亡,只会变异——这正是 Lisp 美学的一部分。 ### 从 Lisp 到 Scheme 再到 Racket 1975年,Gerald Sussman 和 Guy Steele 创建了**Scheme**:一种极简、优雅、近乎数学化的 Lisp。Scheme 成为学术界最喜爱的*编程教学*语言(传奇教材《计算机程序的构造和解释》就使用 Scheme 编写)。 1995年,Matthias Felleisen 团队创建了**PLT Scheme**,一种为教育和编程语言研究设计的 Scheme。2010年它更名为**Racket**,如今它已远不止是 Scheme:它是一个*构建语言的语言*。其非官方格言是*面向语言的编程*:如果你的问题需要自己的语言,Racket 能让你在一个下午内构建出来。 年份|事件 ---|--- 1958|McCarthy 在 MIT 发明 Lisp 1975|Sussman 和 Steele 创建 Scheme 1984|Common Lisp 标准化 1995|PLT Scheme(现 Racket)诞生 2007|Clojure 诞生(JVM 上的 Lisp) 2010|PLT Scheme 更名为 Racket 今天|你,正在阅读此文,即将编写括号(激动) UwU --- ## *当今*谁在使用 Lisp? 比你想象的要多: - **Clojure**在银行、航空公司和初创企业投入生产运行(拉丁美洲最大的数字银行 Nubank 就运行在 Clojure 上)。 - **Common Lisp**(配合 SBCL 编译器)仍活跃于专家系统、飞行规划(被 Google 收购的 ITA Software 驱动着 Google Flights)和科学计算领域。 - **Emacs Lisp**——数百万人每天使用 Lisp 却不自知,因为他们的编辑器*就是*Lisp 解释器。 - **Guile/Guix**——整个 Linux 发行版100%使用 Scheme 配置。 - **Racket**有自己的年度会议(RacketCon),活跃的学术和艺术社区,并用于语言研究、形式化验证(Rosette)、字体排印与出版(Pollen)以及全球教育领域。 - 新 Lisp 方言持续涌现:**Fennel**(编译到 Lua 的 Lisp,常用于游戏开发)、**Janet**、**Hy**(基于 Python 的 Lisp)…… ## TADC 影迷的彩蛋: TADC > 在《神奇数字马戏团》(第8集"hjsakldfhl")中,当 Kinger 打开终端试图重置 Caine 时,可以看到 Caine(一个1996年构建的创意AI)是用 Lisp 编程的。文件名就叫`Caine-core.lisp`。 --- ## 安装(5分钟) 1. 访问 https://racket-lang.org/ 2. 下载适合你系统(Linux、macOS、Windows)的安装包。 3. 打开附带的**DrRacket**环境。 DrRacket 分为两个区域:顶部编写**定义**(你的程序),底部是**REPL**用于实时实验。在定义区域的第一行写入: ```racket #lang racket ``` 这行代码告诉 Racket 你使用的语言(记住:Racket 是语言工厂,必须选择一个)。 如果更喜欢终端:`racket`命令提供 REPL,`raco`是包管理器和工具命令。 --- 在 REPL 中尝试: ```racket > (+ 1 2) 3 > (* 3 (+ 2 2)) 12 > (string-append "hello " "world") "hello world" ``` Lisp 的规则可归结为一行: > 一切都是`(操作符 参数1 参数2 ...)`。始终如此。无例外。 无需记忆运算符优先级,没有特殊语法。`(+ 1 2)`执行加法,`(if ...)`进行判断,`(define ...)`进行定义。起初看似可怕的括号,实则是绝对无任意规则约束的体现。一周后,你将不再注意到它们。 --- ## 定义与函数 ```racket #lang racket (define pi-approx 3.14159) (define (circle-area r) (* pi-approx r r)) (circle-area 2) ; => 12.56636 ``` - 带名称的`define`创建常量。 - 带`(名称 参数...)`的`define`创建函数。 - 注释以`;`开头。 匿名函数使用`lambda`(没错,就是那个1930年代丘奇的λ演算——所有这些的理论鼻祖): ```racket (lambda (x) (* x x)) ; 无名函数 ((lambda (x) (* x x)) 5) ; => 25,直接应用 ``` --- ## 列表:Lisp 的核心 Lisp 是**LIS**t**P**rocessing(列表处理)的缩写。列表是基础结构: ```racket (list 1 2 3) ; => '(1 2 3) '(1 2 3) ; 等效形式,"引用"形式 (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 ``` 注意引号`'`。它告诉 Racket:*不要求值此表达式,这是数据*。记住这个细节——它将通往最终的奥秘。 ### 高阶函数 这是 Racket 大放异彩的领域。将函数传递给其他函数是最自然的操作: ```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`变换,`filter`选择,`foldl`累积。仅这三个函数就能解决大多数列表问题,无需编写单个`for`循环。 --- ## 递归:螺旋式思维 在 Lisp 中你不会想"重复N次",而是思考"基本情况是什么,如何向其推进?": ```racket (define (factorial n) (if (= n 0) 1 (* n (factorial (- n 1))))) (factorial 5) ; => 120 ``` 为使内容更直观,让我们绘制些图形。Racket 自带图形库: ```racket #lang racket (require 2htdp/image) (define (sierpinski level) (if (= level 0) (triangle 8 "solid" "purple") (let ([t (sierpinski (- level 1))]) (above t (beside t t))))) (sierpinski 6) ``` 将其粘贴到 DrRacket,点击运行,即可在屏幕上看到谢尔宾斯基三角形生成。 --- ## 终极奥秘:编写代码的代码 还记得引号`'`吗:它将代码转化为数据。观察: ```racket '(+ 1 2) ; => 列表 (+ 1 2),而非数值3 (first '(+ 1 2)) ; => 符号 + (eval '(+ 1 2)) ; => 3。你刚将数据作为代码求值了。 ``` 你的程序是列表。你可以构建列表。因此:**你可以用程序构建程序**。这就是**同像性**,也是 Lisp 拥有真正*宏*的原因——不是C语言的文本宏,而是在执行前接收代码并返回代码的函数。 Racket 没有`while`循环?让我们发明一个: ```racket (define-syntax-rule (while condition body ...) (let loop () (when condition body ... (loop)))) (define counter 0) (while (< counter 5) (displayln counter) (set! counter (+ counter 1))) ``` 你刚刚**扩展了语言!** 在 Lisp 中,语法由你定义。 Alan Kay 称 Lisp 是*"软件的麦克斯韦方程组"*:一个能推导出所有其他内容的极简核心。 --- ## 下一步? Kurosawa_Ruby_Holding_SICP - **《如何设计程序》(https://htdp.org/)**——Racket 专为其设计的教材,免费在线阅读。 - **《Racket 指南》(https://docs.racket-lang.org/guide/)**——官方文档,是目前最佳文档之一。 - **《Beautiful Racket》(https://beautifulracket.com/)**——学习构建你自己的语言。 - **《SICP》**——经典中的经典,若想获得完整启蒙体验。 ---

相似文章

Racket v9.3

Hacker News Top

Racket v9.3 已发布,包含多项新功能,包括 Markdown 文档生成、改进的教学语言,以及增强的包管理和 FFI 支持。

通往Lisp之路:为何选择Lisp

Hacker News Top

文章阐述了学习Lisp的理由,强调了其宏和可扩展性等独特特性,这些特性使程序员能够将语言适配到自己的问题域,并通过Blub悖论解释了为何来自能力较弱语言的程序员可能难以认识到Lisp的优势。

RacketCon 将于周六举行

Hacker News Top

RacketCon 2026 是 Racket 编程语言社区的第十六届聚会,将于周六举行,届时提供直播,演讲内容涵盖记号表示法、Typed Racket 中的类型推断,以及通过新语言 Pille 实现的底层面向语言的编程。