语言设计成功的奥秘何在? Unix 的开发贡献者之一、Awk 创始人 Brian Kernighan,试图在诺丁汉大学的一次采访中揭开语言设计的神秘面纱。
在此次采访中,Kernighan 将重点放在特定领域的语言上,也就是在特定的应用领域中解决特定问题的语言。这些语言应用范围狭窄,也没有必要图灵完备。Kernighan 对这些语言感兴趣,是因为相比那些复杂的语言,如 C++ 等,这些特定领域应用的语言能为语言设计工作和设计者提供一个更加可行的途径。特定领域中获得成功应用的语言包括正则表达式, shell, Awk, XML, HTML, SQL, R 等。
一种语言的标记符号是其设计的基本组成部分,直接决定了开发者能否毫不费力、不花费多余时间和精力解决特定问题(但可能在其他类型的问题中表现更好)。此外,Kernighan 认为,标记符号将会直接影响我们思考问题的方式。
Kernighan 分析的第一个例子是 Awk,并借用一个模式行为范例来向使用者展示如何操作。Awk 的设计目标是简单的一行式代码,尽管 Awk 可以被“滥用”于书写很长的代码,但是短代码仍然更有效。Awk 语言标记符号的另一个特点是与 C 语言相似,这为使用者节约了更多的时间去学习新语法和语言结构。这也被 Kernighan 肯定为 Awk 语言的优势之一。
一行式的程序语言引导 Kernighan 将更多精力放在制定语言的特定功能上,如无类型声明,自动初始化,内置变量,字符串和数字的转换,支持关联数组和正则表达式,控制流语句和内置函数。
同样重要的是 Awk 的设计使得学习成为可能。首先,人们将采取意料之外的方式运用语言工具,不可避免地犯错误,并且这种现状很难改变。特别地,对于 Kernighan 而言,避免在新的语言中增加新功能,或试图修正或提高特定的功能是很重要的,因为这些行为都会破坏语言的稳定性。另外,事后增加一些新的符号通常会使得语法缺乏一致性。
Kernighan 举的第二个例子是 AMPL,一种数学建模语言,基于一系列值变量和约束条件求解最优化的问题。Kernighan 是这个语言的设计者之一,同时也是语言的最初使用者。AMPL 提供了声明语法,用来描述问题变量和约束条件。AMPL 还提供了数据规范语言来描述数据和命令语言控制 AMPL 的操作。
Kernighan 介绍说,AMPL 的一些特点能使它获得适度的成功。特别地,它只局限于解决特定的问题,大学教学中使用它,使得它很快就在教育行业得到广泛应用。它的符号标记最初是纯声明,后来加入更多机制,如条件语句,循环,函数,即这些实现了语言的图灵完备。这也同时带来了一些奇怪的和不规则的语法。另外,AMPL 是正封闭源代码,这无疑促成了它的成功,但是,正如 Kernighan 所说,这也引起了很多人的探讨。
Kernighan 介绍的第三种语言是 EQN——一种数学排版语言,这是他和 Lorunda Cherry 在 1974 年设计的。EQN 的设计理念是实现按照人们日常读公式的方式来书写数学公式,并且为 TeX 的实现启发了灵感:
x sup 2 + y sup 2 = z sup 2 f(t) = 2 pi int sin(omega t) dt
此语法使用简单,连那些在数学方面并没有很深造诣的贝尔实验室打字员都可以使用 EQN。EQN 的一个重要的基础就是将其输出通过管道馈送到 Troff 中,主要是考虑到在该语言程序被创造时的计算机内存约束。Kernighan 说,依靠现有的工具是实现 DSL 和降低复杂度低的一个很好的方法。
Kernighan 创造的另一种格式编辑语言是 Pic,它试图将文本描述转换成线性绘图。Pic 的优点是:很容易实现系统性的改变,保证正确的尺寸,并使用循环语句和条件创建重复的结构。此外,这种语言正在使用 Troff 作为输出端,并将其插入到 Pic 的预处理器中。Pic 是通过使用 YACC 和 LEX 实施,这更容易依靠语法实现,不需要太多的协调规范就实现了自由的英文式的语法形式。以下是一个简单的用 PIC 实现的流程图:
arrow; box "input"; arrow; box "process"; arrow; box "output"; arrow
基于以上的例子,Kernighan 提出了几个原则,阐释了语言设计取得成功的要点:
- 新的语言能解决实际问题,并且比其它方法做的更好。
- 这些语言是在“文化”上兼容,并且语法结构是相似的。很多语言看上去都类似 C 语言的语法结构,学习起来更容易上手。
- 它们与现有工具生态系统相兼容,不需要重新购买一个完整的新环境,或放弃使用标准工具。
- 它们是开源的——特别是在当下时代至关重要,Kernighan 说道。
- 它们少有竞争对手,这是幸运的。
另外,还有一些因素会导致语言失败,虽然语言从未完全消失:
- 语言存在于一个基于消失的小众应用领域的环境中,正如发生在 Kernighan 所创造的基于 Troff 的语言上面那样。
- 语言或过于庞大、或过于复杂、 或过于迟缓、或出现过晚。这里特别提到两个语言:Perl 6 明显是太晚。C++ 明显太大、太复杂,尽管 C++ 仍然被很多新开发程序使用。
- 它们是基于对贫困哲学的选择,当它们牺牲实用性或太“数学”或太“不同”,这两点都会减少用户的数量。
Kernighan 的最后一句话是引用 Alan Perlis 的话,可以作为创建新语言的一种激励和指导,尝试结合过去的方法来把这些语言做得更好:
“在程序里我们始终有话要说,但是所有已知的语言都无法表达得很好。”
查看英文原文: Brian Kernighan on Successful Language Design
感谢张龙对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。
评论