A Road to Lisp: Which Lisp
196 points • 1 day agoArticle Link

Lisp 不是一种单一的语言,而是由多个编程方言组成的家族——它们共享基本语法,但在运算符、语义和标准库上差异很大。对初学者而言,选择哪个方言并不如掌握 Lisp 那种思维方式重要。因为核心概念在各方言间基本一致,学会一种后转到另一种通常相对容易。

Common Lisp 是最成熟、最全面也最稳定的方言。自 1994 年标准化以来仍广泛适用,几十年前的代码常常能在现代实现(如 SBCL)上直接运行。它开箱即用,功能强大,包括用于调试的 condition/restart 机制和支持多重分派的对象系统 CLOS 。虽然缺少诸如内置模式匹配的现代便捷功能,但能编译为原生代码,使其速度非常快,适合长期运行的服务、研究以及高性能应用。

Clojure 的设计旨在把 Lisp 带入现代生态:运行于 JVM,使开发者能利用现有的 Java 库和生态。它强调函数式编程风格,依靠纯函数和不可变数据结构来管理状态。凭借对并发的良好支持和全栈能力(包括用于浏览器的 ClojureScript),Clojure 可以说是最适合生产环境的 Lisp,广泛应用于金融和数据密集型领域。调试有时会被复杂的 JVM 堆栈跟踪所困扰,但其对简洁性和高产出的追求使其非常实用。

Racket 源自 Scheme 传统,更像是一个面向语言的开发环境。它允许开发者轻松创建新语言或领域专用语言,因此在学术研究和计算机科学教育中备受青睐。 Racket 附带丰富的库,用于构建 GUI 、 Web 服务器等,DrRacket IDE 为初学者提供了友好的入门体验。尽管在工业界的影响力可能不如 Clojure,但其卫生宏系统以及通过 Typed Racket 提供的可选静态类型支持,使其成为进行实验性编程的有力工具。

除了这些通用方言之外,Elisp 作为 Emacs 的扩展语言,承担着专业且非常实用的角色。它允许对编辑器进行实时定制,生动展示了基于 Lisp 的环境如何在运行时被操控。无论选择哪种方言,各有优势:Common Lisp 的原生性能、 Clojure 的现代生态、 Racket 的教学与实验性灵活性。最终该如何选择,取决于你的目标——是追求职业实用、深入系统理解,还是入门语言设计。

159 comments • Comments Link

- Common Lisp 因为标准稳定、规范固定且有 SBCL 等强大编译器而备受推崇,但新手常觉得缺少完整的线程或内建网络支持这类现代功能,因此不得不依赖社区扩展。

- Scheme 以其极简优雅的设计常被推荐为入门语言,是学习核心编程概念和试验自定义语言范式的理想选择,但由于存在多个 R-report 版本,生态略显分裂。

- Clojure 因与 Java 生态的务实互补和优良的开发体验而备受好评,尤其是像 Babashka 这样的脚本工具以及以 REPL 驱动、鼓励快速迭代的工作流。

- 关于 Lisp-1 与 Lisp-2 的争论多属个人喜好:Lisp-1 支持者偏好单一命名空间,认为这样语法更简洁、便于高阶函数;Lisp-2 支持者则认为函数与变量分离的命名空间能避免遮蔽并保持代码更清晰。

- Lisp 的 "homoiconicity"(即把代码当作数据处理的能力)常被视为独特的教学利器,它让开发者更容易构建复杂的 DSL 和编译器,这在灵活性较低的语言中往往难以实现。

- 对 Lisp 可读性的感受差异很大:有人认为 S-expressions 本质上清晰有逻辑,另一些人则不习惯缺乏显式语法标记,常需要结构化编辑器或约定的缩进方式来维持可读性。

- 现代 Lisp 方言在持续演进,像 Jank(Clojure-to-native)与 Coalton(type-safe Common Lisp)等项目,试图将经典 Lisp 的特性与对原生高性能和静态类型检查等现代需求相结合。

- 选择过多是进入 Lisp 生态的一大障碍:众多方言、实现与工具会让初学者不知所措,缺乏先验背景时很难决定从哪里入手。

- Emacs 以其深度可编程性和高度整合仍被视为 Lisp 开发的黄金标准,但有人认为缺乏现代且易用的独立 IDE 阻碍了它的更广泛普及。

- 通过 Lisp 学到的函数式思想——递归、不可变性、高阶函数等——常被称为"改变人生",这些概念为程序员在任何语言中推理复杂问题提供了根本性的思维框架。

讨论凸显了 Lisp 理论之优雅与现代软件开发务实需求之间的张力。参与者虽对 Lisp 带来的思想自由与快速反馈周期充满热情,但也坦率地指出了工具与库的不成熟、以及与 S-expression 语法相关的学习曲线等实际挑战。总体来看,讨论强化了一个观点:Lisp 不只是一种单一语言,而是一种强调交互性与可扩展性的编程哲学,持续影响着现代语言设计与开发者工作流。