← 返回信息流
AI 资讯Hacker News·2 小时前

Lisp学习指南:如何选择适合自己的方言

原标题:A Road to Lisp: Which Lisp

速览

Lisp有多种方言,如Common Lisp、Scheme和Clojure,各有优劣。本文从学习曲线、应用场景和生态系统出发,帮助初学者或开发者根据自身需求做出选择。理解这些差异有助于更高效地掌握Lisp语言。

AI 深度解读

背景

Lisp 是一族编程语言,而非单一语言。与 Python、Java、JavaScript、C++ 等主流语言不同——它们虽有多个版本和实现,但本质上仍是同一种语言——Lisp 拥有超过 20 种不同的方言。初学者常面临一个困惑:应该先学哪一种 Lisp 方言?本文来自 Hacker News 上的一篇文章《A Road to Lisp: Which Lisp》,旨在帮助读者了解最活跃、最常用的 Lisp 方言,并重点介绍 Common Lisp 的特性、优缺点及适用场景,为初学者提供选择指南。

核心内容

Lisp 的独特性

大多数编程语言以单一语言形式演化。例如,C 和 C++ 可用 GCC 或 Clang 编译,Python 可用 CPython 或 PyPy,同一段 JavaScript 在 Firefox 和 Chrome 上都能运行,Java 程序可运行在 JVM 或 GraalVM 上。但 Lisp 并非如此。维基百科列出了超过 20 种不同的 Lisp 方言,它们共享基本语法,但操作符、语义、标准库和语言能力各不相同。

初学者常问“应该先学哪种方言”。答案是:方言虽然重要,但远没有初学者想象的那么关键。学习 Lisp 本质上是学习一种新的编程范式,一种用代码思考问题的新方式。无论选择哪种方言,你都会学到核心概念。掌握一种之后,切换到另一种会相对容易。

最相关的 Lisp 方言:Common Lisp

Common Lisp(简称 CL)是所有 Lisp 方言中最成熟、最全面的,被视为“老派”Lisp。该语言于 1994 年通过 ANSI 正式标准化,因此存在多种实现,可针对不同平台和用例。最著名的实现是 SBCL,它直接编译为原生代码,速度快、开源且与现代硬件兼容。编写良好的 Common Lisp 代码性能可达 C 和 Rust 的水平。由于 SBCL 优化力度大,编译速度稍慢,但生成的代码在 Lisp 家族中属于最快之一。

Common Lisp 是功能最全面的方言,开箱即用提供大量功能,许多功能直接定义在标准中。例如,它内置了从语言内部控制编译和求值的函数(如 COMPILELOADEVALCOMPILE-FILE 等),可在代码或 REPL 中调用,告诉 Lisp 进程编译函数、加载文件或求值代码。它还提供 DISASSEMBLE,允许检查编译后函数的机器码。

Common Lisp 拥有条件与重启系统,这是作者见过的最强大的调试和程序检查方式之一。执行过程中若出现条件(condition),Lisp 进程可以暂停,让你检查程序的状态和变量,然后选择重启程序、重试操作,或忽略条件继续执行。这得益于 Common Lisp REPL 与运行系统的深度集成。如果程序在远程服务器上失败,你可以连接到它的 REPL 并检查实时进程,了解哪里出了问题。

Common Lisp 支持所有主流编程范式:函数式、命令式、元编程和面向对象编程。它提供最先进的对象系统之一 CLOS,支持多重分发和泛型函数,使 OOP 比 Java 或 C++ 等常见面向对象语言更灵活。此外,Common Lisp 是动态类型语言,但拥有丰富且富有表现力的类型系统,支持可选类型声明。

标准化意味着语言稳定。1994 年的 ANSI Common Lisp 至今仍在使用,因此 Lisp 程序员很少遇到向后不兼容问题,旧的 Common Lisp 代码通常仍能完美运行。例如,Peter Norvig 于 1991 年出版的《PAIP》中的代码,许多在现代实现上仍可运行。Common Lisp 遇到的不兼容问题远少于 Ruby 和 Python 这类语言。即使长期未更新的 Common Lisp 库,通常也能在系统上正常运行,因为它们无需持续适应新版本。

Common Lisp 的不足

Common Lisp 缺乏一些在新语言中已变得常见的便利功能,例如更广泛数据结构的简洁字面量、持久化不可变集合、惰性序列和内置通用模式匹配。设计于 1980 年代的 Common Lisp 是合并多个已有 Lisp 方言而成的,设计师保留了旧方言的许多语法和模式,确保现有 Lisp 程序员无需学习全新语法即可采用该语言。

Common Lisp 没有中央方向或企业赞助商。社区相对较小,分散在多个实现、项目和通信渠道中,主要由志愿者维持语言活力。寻找指南和帮助可能有些困难:教程要么过于简单,要么过于高级,文档也不容易找到。

实际应用

Common Lisp 目前用于 Rigetti Computing 的量子计算,曾在 Grammarly 用于其核心语法服务,并支撑 Google Flight Search。值得一提的还有 Kandria,一款在 Steam 上发布的开源视频游戏,完全用 Common Lisp 编写。有趣的是,Paul Graham 最初用自制 Lisp 方言 Arc(基于 Racket)编写了 Hacker News。如今,Daniel Gackle(@dang)用 Clarc(一种运行在 SBCL 上的 Arc 的 Common Lisp 实现)重新实现了它,每天服务约 1000 万页面。

Common Lisp 的闪光点

Common Lisp 在所有主流操作系统上编译为原生代码,可实现快速执行,代价是启动稍慢,因此非常适合长时间运行的过程。它提供了 Lisp 方言中最强大的 REPL 之一,尽管学习曲线陡峭,但可以说是短时间内编写可靠软件最快的语言之一。当需要快速迭代的研究和原型开发(如量子计算),或需求未完全定义、频繁变更(如初创公司)时,Common Lisp 表现出色。Paul Graham 曾写过一篇著名且鼓舞人心的文章,讲述 Common Lisp 如何帮助他的互联网初创公司击败竞争对手。

学习资源

  • 起点:Steve Losh 的《A Road to Common Lisp》,本文作者受其启发写就此系列。
  • 初学者最易读的书籍:Peter Seibel 的《Practical Common Lisp》,全书在线可读,是作者读过的最佳入门介绍,重要概念清晰分章。
  • 趣味入门:Conrad Barski 的《Land of Lisp》,用有趣的角色和漫画通过游戏教授编程。
  • 进阶书籍:Paul Graham 的《On Lisp》,完全专注于宏。
  • 最佳 IDE 支持:Emacs + Sly/Slime(Doom 已支持),或 Vim + VLime。较弱选择:VSCode + Alive。
  • 初学者最佳资源:The Common Lisp Cookbook,包含许多最新教程。
  • 参考资料和库:Awesome Common Lisp 列表。

关键要点

  • Lisp 是语言家族:超过 20 种方言,核心语法相同但操作符、语义、标准库各异。
  • 方言选择对初学者不重要:学习 Lisp 是学习新编程范式,掌握一种后切换其他方言相对容易。
  • Common Lisp 是最成熟、最全面的方言:1994 年 ANSI 标准化,稳定且向后兼容性好。
  • SBCL 是最著名实现:直接编译为原生代码,性能接近 C 和 Rust,但启动稍慢。
  • 强大特性:内置编译求值函数、条件与重启系统、CLOS 对象系统(支持多重分发和泛型函数)、动态类型但可选的类型声明。
  • 不足:缺乏现代便利(如模式匹配、惰性序列、不可变集合等),社区较小,文档和教程质量参差不齐。
  • 实际应用:量子计算(Rigetti)、Grammarly 核心语法、Google Flight Search、游戏 Kandria;Hacker News 运行在基于 Common Lisp 的 Clarc 上。
  • **学习
查看原文 →scotto.me