前言

前言

我曾经在 Linux 专业期刊《日经 Linux》上开设了名为“边做边学编程语言”的专栏(2014 年 4 月~ 2016 年 12 月),本书就是对这个专栏的系列文章加以汇总,并添加了一些新的内容编辑整理而成的。

以自制编程语言为主题的书非常多,我家的书架上也放了好几本。这些自制编程语言的书绝大部分是介绍编程语言的实现的。比如以比较简单的语言的实现作为示例,介绍如何使用 yacc 和 lex 工具制作语法分析器和词法分析器,如何实现解释器等。

不了解真实情况的人总以为编程语言的实现需要高超的技术,非常困难,但如果循序渐进地进行实际操作,就会发现其实并没有那么难。实际上,在大学的计算机科学课程中,也有不少实现语言处理器之类的作业。在以年轻人为对象的编程竞赛中,比如我长期担任评委的 U22 编程竞赛,甚至有高中生挑战自制编程语言。

抛开成见认真去做的话,你会发现编程语言的设计与实现对程序员来说是一项非常有趣的智力挑战。在这个意义上,这些关于自制编程语言的书是有其存在价值的。

但这并不是说我对这些书没有不满。这些书顶多是对编程语言的实现的解说,作为示例使用的语言也几乎都是现有语言的(过于简化的)子集。而对于创建编程语言的过程中最挑战智力也最有趣的语言设计部分,可以说完全没有涉及。

不过这也是没办法的事,可以理解。为了有效利用有限的页数,缩小主题是必然的。如果不限定为简单的语法,那么无论如何也很难讲完。再往深里说,也没有多少人有设计全新的编程语言的经验,更不用说自己设计的语言在全世界被广泛使用了,可以毫不夸张地说,根本没有这样的人。

也就是说,几乎没有人能根据自己的经验来讲述如何设计编程语言。因此,将语言的设计作为后话,优先讲解语言处理器的实现技术,可以说是必然的。

其中也有少数例外的情况,比如 C++ 设计者本贾尼·斯特劳斯特卢普(Bjarne Stroustrup)所著的 The Design and Evolution of C++ 1 一书。这是一本非常宝贵的书。读了这本书,你就可以了解 C++ 为何是现在的样子,它的目标是什么。不过是否能靠这本书学会语言设计的方法,那就另当别论了。

1中文版名为《C++ 语言的设计与演化》,裘宗燕译,科学出版社 2012 年出版。——译者注

既然世界上不存在这样的书,那就只能自己去写了。幸好我拥有在全世界被广泛使用的编程语言的设计经验,有这种经验的人屈指可数。另外,我兴趣广泛,对世界上各种编程语言的设计都有所了解。再者,我在《日经 Linux》上连载过文章,还有多本书的写作经验。因此,要写关于设计编程语言的书,恐怕整个日本没有人比我更合适了吧(自吹自擂)!

有了这个想法之后,我便从《日经 Linux》2014 年 4 月刊起开设了专栏,开始发表该主题的文章(表 1)。

从创造编程语言的动机,到思考语言设计时的内心纠葛……本书提到了很多其他同类书中不曾涉及的内容,对此我也颇为骄傲。

但是在把每个月连载在杂志上的内容汇总成书时,一个难逃的宿命就是,随着时间的推移,会出现内容前后矛盾等问题。本书也不例外。

连载时的主题如表 1 所示。其中,嵌入式 Ruby“mruby”相关的介绍(2014 年 4 月刊和 2014 年 6 月刊的一部分)以及超出本书范围的相关说明(2014 年 9 月刊~ 2014 年 11 月刊)均未被收录在本书之中。另外,我还调整了连载的前后顺序,并结合 Streem 的现状修改了部分内容。

但是,整体的文章结构与连载时相比并没有大的变动。因此,为了保持内容的连贯性以及帮助各位读者理解,我在每节的末尾添加了“时光机专栏”,这是对正文的补充。在这部分内容中,我会站在现在的角度审视过去的连载主题有哪些不足之处。

“时光机专栏”的存在,好像是向世人承认自己的能力有限一样,这令我心情复杂,但想到谁也无法预知未来,我也就释然了。

接下来就由我带领大家进入编程语言设计的世界吧!

松本行弘

2016 年 12 月

表 1 连载主题一览表

《日经Linux》刊登期号

标题

本书

2014 年 4 月刊

第 1 期 编程语言设计入门

1-1

2014 年 5 月刊

第 2 期 语言处理器的结构

1-2

2014 年 6 月刊

第 3 期 虚拟机

1-3

2014 年 7 月刊

第 4 期 编程语言设计入门(前篇)

1-4

2014 年 8 月刊

第 5 期 编程语言设计入门(后篇)

1-5

2014 年 9 月刊

第 6 期 编程语言的类型设计(1)

-

2014 年 10 月刊

第 7 期 编程语言的类型设计(2)

-

2014 年 11 月刊

第 8 期 编程语言的类型设计(3)

-

2014 年 12 月刊

第 9 期 抽象的并发编程

2-1

2015 年 1 月刊

第 10 期 21 世纪的并发语言

2-2

2015 年 2 月刊

第 11 期 设计 Streem 语言

2-3

2015 年 3 月刊

第 12 期 Streem 语言的核心

2-4

2015 年 4 月刊

第 13 期 多线程与对象

2-5

2015 年 5 月刊

第 14 期 缓存与符号

2-6

2015 年 6 月刊

第 15 期 AST

2-7

2015 年 7 月刊

第 16 期 局部变量与异常处理

2-8

2015 年 8 月刊

第 17 期 套接字编程

4-1

2015 年 9 月刊

第 18 期 CSV

5-3

2015 年 10 月刊

第 19 期 基本数据结构

4-2

2015 年 11 月刊

第 20 期 各种各样的面向对象

3-1

2015 年 12 月刊

第 21 期 Streem 的面向对象

3-2

2016 年 1 月刊

第 22 期 对象表示与 NaN Boxing

4-3

2016 年 2 月刊

第 23 期 垃圾回收

4-4

2016 年 3 月刊

第 24 期 管道编程

5-1

2016 年 4 月刊

第 25 期 管道的组成要素

5-2

2016 年 5 月刊

第 26 期 无锁算法

4-5

2016 年 6 月刊

第 27 期 时间表示

5-4

2016 年 7 月刊

第 28 期 统计基础

5-5

2016 年 8 月刊

第 29 期 再看 Streem 的语法

3-3

2016 年 9 月刊

第 30 期 模式匹配

3-4

2016 年 10 月刊

第 31 期 随机数

5-6

2016 年 11 月刊

第 32 期 数据流图

5-7

2016 年 12 月刊

最后一期 后记与拾遗

-

目录