为什么 Common Lisp 不是最流行的编程语言?

Common Lisp 持久的神秘感与其有限的采用形成鲜明对比:许多程序员赞赏它的宏系统、交互式 REPL、条件处理和长期稳定性,但也觉得语法、对链表的重度依赖以及多命名空间语义难以阅读和教学。评论者认为,碎片化的工具与库、缺少一个占主导地位的实现或包生态,以及缺乏大型企业赞助,使得 CL 没能成为工业界的默认选择,尤其是与 C 派生语言、Python 或 JavaScript 相比。大家普遍同意,虽然 Lisp 仍然是小型专家团队和小众领域中强大而灵活的“工具箱”,但它的灵活性、重 DSL 风格以及历史包袱,使它并不适合大型、可替换性强的工程组织和主流入门场景。

历史与网络效应

  • 早期的 Lisp 需要昂贵的硬件;等到机器性能跟上、CL 又完成标准化时,C 和 Unix 早已在心智份额上胜出。
  • AI 寒冬扼杀了商业 Lisp 厂商;如今没有像 Sun/Oracle 之于 Java 或 Python 的大型、显眼的支持者。
  • 人们认为,流行度更多由网络效应和企业赞助驱动,而不是由技术优越性决定。

生态、工具与部署

  • 包管理被描述为碎片化且薄弱;存在多个相互竞争的工具,对于序列化或异步之类的功能,也几乎没有收敛到“一个显而易见”的库。
  • 也有人认为这个生态比外部人想象的更广泛、更稳定(Quicklisp、FFI 辅助工具、许多库),但它更难发现,而且缺少类似 Stack Overflow 那样的支持。
  • REPL 和基于镜像的工作流受到称赞(conditions、restarts、远程调试、增量开发),但自由实现的 CLI REPL 体验在没有编辑器集成时被认为很粗糙。
  • 二进制体积和部署问题存在争议:SBCL 可以生成独立二进制,但体积相对较大;商业实现做得更好。

语言设计:能力 vs 可接近性

  • 支持者强调宏、基于表达式的设计、多重分派(CLOS)、condition/restart 系统、增量类型、FFI,以及标准长期稳定。
  • 批评者把 CL 看作一个“杂货铺式”的语言,带有历史包袱(函数与变量分离的命名空间、以 cons 为中心的列表、古老的 pathname 模型)。
  • 有人认为 CL 是“让难事变简单,但让容易的事变难”:日常数据结构(向量、映射)和列表易用性都不如现代语言。

列表、括号与语法

  • 许多评论者说主要障碍是语法:大量括号和以链表为中心的习惯让人感到陌生且难读。
  • 另一些人反驳说,只要有结构化编辑器、缩进和熟悉度,括号其实会“消失”;真正的问题是惯用的列表处理风格很陌生。
  • 对链表本身也有争论:有人认为相较于数组和映射,它们已经过时;也有人认为它们非常适合探索式编程,但为了性能必须替换掉。

宏、DSL 与可维护性

  • 宏和 reader macros 被视为 CL 的杀手级特性,同时也是它的诅咒。
  • 爱好者重视“写代码的代码”和领域专用抽象;反对者则认为每个代码库都变成自己的方言,增加了认知负担,也让大型团队维护变得困难。
  • 讨论中还拿 Haskell 扩展和 C++“子集”作类比:缺乏强约定的灵活性可能产生只能读写者自己理解,或高度怪异的代码。

企业、社区与文化

  • 不少人认为 CL 更适合小型、专家型团队,而不适合那些希望开发者可替换、约定严格且招聘容易的大组织。
  • 有人觉得 CL 社区更个人主义,标准化和接受补丁的速度较慢,而且缺少凝聚力强的会议/基金会结构。
  • 也有人报告说在职业场景中使用 CL 很愉快,并反驳它不可维护或对初学者特别有问题的说法。

与其他语言的比较

  • Clojure 被提及为一种借助 Java 生态系统和不可变数据结构的“现代 Lisp”。
  • Julia 被指出受 Lisp 影响,拥有宏和多重分派,但仍然年轻,并且在处理二进制体积和 restarts 等问题。
  • Rust、Go、Python 和 JavaScript 经常被拿来对比:它们受益于强大的生态、工具和企业支持,即便它们比 CL 带来更多约束或复杂性。