Lisp 的优势:来自 Viaweb 早期 Web 架构的启示

在桌面软件由操作系统原生语言(主要是 C)主导的时代,向服务器端 Web 应用的转变开启了语言自由的新前沿。开发者第一次能够完全控制自己的环境,允许他们根据功能和生产力而非兼容性来选择工具。

这种自由是 Viaweb 的催化剂,Viaweb 是在线商店创建领域的早期先驱。通过利用 Lisp,Paul Graham 和他的团队能够超越那些仍然受限于 C 和 C++ 的竞争对手。他们获得的的技术优势不仅仅是学术性的;这些优势直接转化为更快的发布周期、更复杂的功能,以及在实时处理 Bug 的卓越能力。

增量开发的哲学

Lisp 最深刻的优势之一是它对增量开发的支持。Lisp 不遵循传统的“设计-构建-测试”周期,而是鼓励一种流程:程序员从一个最小化的工作程序开始,然后逐渐添加功能,确保代码始终是可运行的。

Graham 指出,Viaweb 编辑器就是这种极端方法的产物。它最初只是一个简单的 120 行程序,后来成长为一个 25,000 行的系统,而从未需要过一次完整的重写。这种方法论与 Web 软件的“滚动发布”性质完美契合,允许持续的改进流和快速转向。

通过交互式 Toplevel 进行快速调试

Lisp 的交互式 toplevel(即 REPL)从根本上改变了 Viaweb 处理客户支持的方式。因为应用程序运行在公司自己的服务器上,团队可以利用真实的用户数据在实时环境中重现 Bug。

当报告一个 Bug 时,Graham 可以将代码加载到 Lisp 解释器中,登录用户账号,并触发一个 break loop 来寻找确切的故障点。这使得周转速度几乎达到了“诡异”的程度:

如果我们能在用户还在电话中时就捕获并修复 Bug,我们甚至很想给用户一种错觉,让他们觉得那是他们自己的幻觉……当用户重新登录时,他们会得到修复了 Bug 的新版本软件。

利用宏和嵌入式语言

Lisp 宏为生成 HTML 提供了结构化优势。由于 HTML 是递归的并使用类似前缀的表示法,它能自然地映射到 Lisp 的 s-expressions。这使得 Viaweb 可以将 HTML 生成视为一系列嵌套的宏调用,从而使复杂的页面变得易于管理。

这促成了 Rtml 的创建,一种用于描述 Web 页面的嵌入式语言。虽然最初是为 Web 顾问设计的,但 Rtml 最终发挥了三个关键功能:

  1. 升级路径: 它为高级用户提供了对其页面的绝对控制权,即使只有一小部分用户会使用它。
  2. 反馈循环: 通过分析高级用户如何修改 Rtml 模板,团队可以识别默认模板中缺失的功能,从而有效地将 Rtml 作为产品缺口的“警告信号”。
  3. 架构分层: Rtml 创建了一个高层抽象层。修改顶层模板是低风险且快速的,而对 Rtml 引擎本身的修改被视为严肃、不频繁的架构转向。

Graham 还强调了这种设计中 keyword parameters 的重要性。通过让 Rtml 运算符使用 keyword parameters,团队可以在不破坏现有模板的情况下添加新功能,从而确保在滚动发布过程中的向后兼容性。

使用闭包解决无状态性

Web 会话本质上是无状态的,这通常迫使开发者依赖僵化的 CGI 脚本和表单提交。Viaweb 通过使用词法闭包(lexical closures)来模拟子程序式的行为,有效地实现了一种延续传递风格(CPS)。

Viaweb 并不生成指向特定脚本及参数的链接,而是生成触发特定代码段的链接——即捕获了周围上下文的闭包。这使得复杂的、多步的用户交互成为可能。例如,当用户需要为房产选择一个颜色时:

  • 用户会点击颜色色块旁边的“Change”按钮。
  • 系统会触发一个闭包,将用户带到颜色选择页面。
  • 在选择完成后,用户会被系统“返回”到原始的编辑页面,并带有新的值。

对于用户来说,这感觉像是一个是一个高级应用;对于开发者来说,这就像是在调用一个子程序,尽管 HTTP 协议是无状态的。

现代视角

虽然 Viaweb 的演讲稿是在 2001 年,但 Lisp 方式的核心原则仍然具有相关性。现代开发者继续在交互式开发周期和 DSLs (Domain Specific Languages) 的力量中发现价值。

社区讨论强调 Lisp 对于现代 Web 应用仍然是可行的。从使用 Common Lisp 配合 HTMX 或 Datastar,到 ScreenShotBot 等产品的成功,投入“合适量的学习时间与精力”仍然可以产生生产力倍增器。正如一位贡献者所言,一个使用这些工具的小型程序员团队往往能比使用更传统、灵活性较低的软件栈的庞大团队表现得更好。

Sources