Build——那个回不去的瞬间

我一直怀念 20 多年前 Delphi 给我的感受,编译型语言的严肃质感,构建出一个可在 GUI 操作系统上直接运行的,实体可执行文件的满足感。然而这种感受自 2006 年逃离 Windows 开发后我几乎再也没有重新获得。

我见识了 PHP 解决问题的 Quick & Dirty,见识了 Ruby 在代码表达能力上的优雅,我感受了现代工具链的便利、严谨与工程正确的三位一体;我见到了设计随意的浏览器脚本语言 JavaScript 蜕变为严肃通用语言,我也见到现代编译型语言 Go Rust Swift 如雨后春笋茁壮成长。

然而所有这些,都没有能再给我 Delphi 给我的独特感受。虽然工作用得最多的是解释型语言(Ruby、JavaScript、早期 PHP),但我心里一直都在怀念那个 compile 的过程,那个 build 的瞬间,以及与「实体」构建产物的认知触碰。解释型语言无法给我这些,即便前现代解释型语言运行平台就出现过打包的概念,但我知道那些「实体部署包」不过是源代码文件的压缩包,它们并没有被带有某种奇幻魔法般神奇能力的工具(编译器)转换为 CPU 直接可读可理解可执行的,精确高效的机器指令。任何一个受过计算机基础教育的人都能具身地理解这之间的区别。

TypeScript 作为 Delphi 设计者 Anders Hejlsberg 在新世代的创造物,确实给 JavaScript 补充了严肃质感。它也实现了编译构建另一个实体的过程——然而其产物只是 JavaScript 源代码,并非我们提到的 CPU 直接可读可理解可执行的二进制机器指令实体。

而所有这些现代语言,除 Swift 外都没有一个拥有 Delphi 那样官方、高完成度、社区丰富的 GUI 应用开发框架。Swift 有,但是无论 AppKit 还是 SwiftUI 都根植于 macOS 的开发体验,而后者跟 Windows 开发体验有巨大的区别,甚至可以说接近某种本质区别。

我曾经跨越几年时间多次投入精力完整阅读 Swift Programming Language 一书,尝试从最基础的语言层面建立可靠的 macOS 开发根基。然而在其上层,macOS 给我的感觉始终是模糊粗糙的。我无法像 Windows 和 Delphi 时代那样找到 VCL 简洁明了的封装,我也无法通过 MSDN 那样的权威文档找到清晰的 Win32 API 信息。Xcode 的文档和它的 UI 一样天然带有某种或许源自 macOS 本身的,面向最终用户时试图隐藏一切技术细节的气质,这种气质阻碍我对系统内部工作原理的深入认知。或许对于 Apple 的文化来说这是一种隐藏细节的封装,然而对于任何一个严肃的系统 hacker 来说都是犯罪。

另一方面,也正因为见过所有这一切,我已经无法回去使用 Delphi——无论是当初的 Delphi 7 还是现代的最新版 Delphi 都不行。我知道它们一定没有精巧的现代工具链,Delphi 的语法和语言特性在我眼中也已经变成了上个时代的陈旧古文。这种陈旧不只是一种质感,也确实基于显著的语言实际表达能力区别。

人生若只如初见,不管纳兰性德写这句话时是否有表达这样的感受,我认为它也一定带了「因为历经铅华所以无法再满足于纯粹却又粗粝的起点」的意味,否则它担不起「人生」这个词的重量。

想要通过回到过去,回到起点去追寻最初的纯粹的感动与满足,这显然是注定会失败的悲剧。消耗巨大的能量,确实可以制造局部熵减,确实可以制造局部的时光倒流,但我们自己的记忆、体验与大脑,我们被经历所刻画的审美品味、认知经验与人格特质,这些是绝对无法倒流的,否则就是对「人生」的根本否定。

补注

做 Veil 的经历让我想到这件事的另外一边:macOS 的 app bundle 设计我从一开始就没有好感——哪怕它确实很实用。我怀念 NSIS 那样设计精巧的 installer 制作工具,它带来的对于「软件安装」这一过程的仪式感,以及软件可执行文件与材料信息丰富不可随意移动的暗示,都是一种软件安装的严谨性与可靠性承诺。然而 app bundle 非常随意,你似乎可以把它扔到任何地方然后正常运行。在 Windows 时代我们也会这么做——20 多年前我就会自制「绿色软件」(portable software)。其本质是通过使用经验和一定程度的探索与反向工程,弄清楚特定软件的运行机制与读写数据依赖,然后将其安全地移动到想要的目录,并且通过修改注册表和配置文件等手段来重新定位,使其能继续正常运行。所有这一切,都给我一种极高的透明度与掌控感,app bundle 不是不能给这些,而是天生就暗示了我追求的严谨性和掌控感是没有意义的。此外,single executable binary 给人的质感印象也与 app bundle 完全不同。前者高度自包含、清晰、内敛,后者像是麻袋随意装起来的一堆杂物。

后记(2026 年 10 月)

这几个月我用 Rust 写了好几个 app,又一次站到了 build 的瞬间面前。很多条件都回来了:编译型语言,产物是一个货真价实的 single executable binary,是 CPU 直接可读可执行的机器指令;cargo build 慢得让每一次构建都成为一场仪式,仪式感甚至强烈到让人不耐烦。GUI 依然没有回来,Rust 没有 VCL,只有社区里各有取舍的几个框架。

但更大的缺失在别处。如今我的开发全在命令行里完成,敲一下 just reload,构建和启动一气呵成,很多时候连运行它的都不是我,而是 Claude Code。那个 binary 安静地躺在 target 目录里,我几乎从不去看它一眼。二十多年前,在 Delphi 里按下 F9 之后,我会在 Total Commander 里看着 EXE 文件出现,看它的大小,打开 File Info 看里面的版本信息,那份精致让我反复端详。正文里说的与「实体」构建产物的认知触碰,指的就是类似这样的事。

我不会为了再看一眼文件大小,放弃 just reload 回到 Total Commander,这和我回不去 Delphi 是同一件事。

真正回不去的,不是那个 build 的瞬间,而是我自己。