Robert Nystrom 是一位拥有 20 年工作经验的软件工程师,之前在 EA 做了 9 年多,2010 年入职 Google,目前工作在 Dart 项目。
2009 年开始写一本设计模式方面的书,叫 Game Programming Patterns,写到一半发现自己对编程语言实现很感兴趣。强忍着兴奋继续写第一本,直到 2014 年第一本书完成.。这本书收获很高的评价,建议想学习设计模式的同学看看这本书,电子版本的完全公开。
而后就开始了第二本关于编程语言实现的书,断断续续写了这么多年,直到 2020 年完成了:Crafting Interpreters,整个过程居然花费了接近 10 年时间。
在这篇 Crafting “Crafting Interpreters” 中,作者详细记录了完成这本书的过程。反正我看完后很震惊,一本技术书籍可以按照这种制作工艺和水准,最后的成书是我见过的质量最高的技术书籍,而且成书和代码可以完全免费阅读!
其实写技术书是投入产出比很低的事情,只有纯粹的热情才能让一个人花这么多年去写这种书。为了完成这本书,作者看了这么多关于语言实现的书:
里面的插图是自己手画的,配文是手写的,完成之后再通过扫描机扫描成电子版本:
所有想深入学习编程的人都应该去理解一个编程语言是如何实现的,因为:
- 克服对语言的恐惧,解释器、编译器不过是另外一个程序。我们可以自己去实现一些常见的语法和特性,编程语言对我们是可以改变和理解的工具,而不是黑盒。
- 这是一个绝佳的提升编程技能的方式。
- 工作中会接触到各种小语言和 DSL (Domain-specific language),parser 或者编译相关的技能可能会有用。
我大学本科的时候挂了一门课叫做形式语言和自动机,这门课当然是对 Parser 很重要的,但是我觉得枯燥之极,我记得需要手画状态机。
后来我工作之后,找了一些具体的代码来看,才能理解状态机这些东西如何应用在实际中。所以,我认为在学习编程中最重要的还是读代码和写代码。我通过读 Essentials of programming languages 学到了很多编程语言相关的东西,在这里面可以实现好多小解释器。
理解编程语言的过程中,Parser 只是其中第一步,而且也是不重要的一步。Parser 如何做已经有了很成熟和规范的做法,一门编程语言更重要的是语法、语义和实现。编译部分又涉及到更多底层和高深的东西,现在 LLVM 是常用的编译后端。所以要理解一门编程语言的实现,一个小语言的解释器就是很好的方向。
在这本书里,作者详细讲解了一个解释器的两遍实现,第一遍用 Java 实现,注重主要概念和原理;第二遍用 C 实现,bytecode、VM、GC,注重优化和底层实现。
这些主题对于非编译器从业人员来说已经足够了。编程语言的实现比很多日常项目难,但这值得一个想更深入学习编程的人锻炼:
长跑运动员有时在脚踝上绑上重物,或者在空气稀薄的高海拔地区进行训练。
然后卸下包袱时,相对轻松的四肢和富含氧气的空气使它们跑得更远更快。
另外这本书中有一些英语俚语,不过不会对阅读造成干扰。相比较 EOPL,我更推荐这本书来学习编程语言原理,因为 EOPL 偏函数式一些,相对更小众。