思考:DSL 用不着像英语

  • Sadek Drobi
  • 郭晓刚

2008 年 4 月 8 日

话题:架构语言 & 开发

很多人都认为好的 DSL 应该是类似于英语的,好让非程序员也能阅读。Dave Thomas 强烈反对这种看法,他主张DSL 的关键不在于尽可能接近自然语言。他更进一步认为把接近自然语言作为设计 DSL 的主导原则是非常有害的。他还列举了他心目中的若干 DSL 设计的要点,并提供了一些例子来说明怎样才是成功的 DSL。

按照 Dave 的说法,DSL 不需要接近于英语或其他任何自然语言,因为 DSL 面向的是非常特定的一类用户——领域专家——他们实际上在自己的专业领域并不说自然语言。

领域专家 [……] 说的是行话,一种为了在同行之间简洁高效地沟通而发明出来的专门的语言。虽然行话里面也用英语的词汇,但这些词汇的含义其实已经经过调整,大异于它们在一般英语中的含义——也就是说你只有在该领域浸淫过才能学会。

因此,DSL 应该反映出这种行话,并简明扼要地表达领域专家的专门知识。Make 依赖管理方面、Grooby Builder 在代码中表达数据方面,Ruby 中的 Active record 数据建模声明这几种 DSL 都是成功的例子,它们响应了领域专家的需求,而且与英语并不相似。虽然 Active record 声明中的某些语句看着有点像英语,比如 has_many 和 belong_to,但事实并非如此:“它们其实是建模领域的行话”,“它们在那个语境中有着特定的含义。”

Dave 还提出了另一个重要的观点,“领域专家”不应该被认为等同于业务用户,他们应该是编写规范的人。他们是程序员。他们并不需要一种类似英语的语言。Dave 实际上认为连贯接口的概念常常被误解:“这里的连贯性指的是程序员的连贯性,不是英语的连贯性。连贯是为了写出简洁而富于表达力的代码”。

Dave Thomas 主张,试图使 DSL 近似于自然语言不但没有必要,而且是有害的。自然语言是不精确的。虽然在现实世界中不精确的语言是一种力量,但它并不适用于编程。这也就是为什么“每次当我们打算建立一种近似于自然语言的 DSL,都达不到目标”。不管如何努力,句法总趋向于变得非常“不英语”。而实际产物与自然语言之间的间隙相当令人困扰:

这里有一个重大的认识上的分歧——我必须先取得用自然语言表达的想法(对问题的描述),然后将它映射到一种人工语言(AppleScript 编程模型),而随后却要写一种虚假的自然语言。

为了演示其中可能出现的混淆,Dave 给出了一段测试代码作为例子,代码是用 test/spec 框架编写的。他分析了如下的表达式:

@result.should.be.a.kind.of String

读起来很像英语。但它并不是英语。单词之间是用点号分隔的,但最后两个词是例外,它们之间用空格来分隔。作为程序员,我很清楚为什么会这样写。但作为一个用户,我会感到担心。上面的例子写的是 @result.should.be.a.kind_of,为什么它不直接写 kind.of?如果我想测试一个浮点数是否大致等于某个值,我必须写成 @result.should.be.close value。为什么不写成 close.to value 呢?

虽然我举的都是微小的细节,但这些细节说明我不能仅凭自己的英语知识能够编写测试——我必须先查阅语法说明。既然如此,那么为什么不干脆直接用一种与规范和测试紧密相关的语言 /API 呢?

近似英语的 DSL 确实可读性更好,但 Dave 认为“为了强让 DSL 带上自然语言的感觉,会使抽象出现各种各样的漏洞”。虽然有可能增加代码的可读性,但是同时会在“可写性”方面遭受损失,而且“增加了不确定性,也使含义模糊”。

如果你写出下面的代码

def a

self

end

那么就意味着可以把“a”作为连接子用在下面的语句中:

add.a.diary.entry.for("Lunch").for(August.10.at(3.pm))

很显然你已经走得太过头了。这已经不是 DSL,而是拙劣的英语了。

有一位留言的读者也认为,试图让一种语言对非程序员可读,最终有可能会落到“只读语言”的境地。他举 AppleScript 为例,为了提高可读性,AppleScript 有必要去除“描述了语言的语义的大多数常见的符号”。结果“不但没有使语言的语义更清晰,反而大大模糊了”。就算“很容易阅读一段 AppleScript 代码并理解它想干什么,但要想确切搞清楚它是怎样做的变得极度困难”。

Has 提出使用近似英语的 DSL 还有另一个值得注意的问题:用户会假设“既然它看起来像英语,那么它的行为应该也和英语一样”,并且“对语言的本质产生种种非常强烈的联想和结论,以后再要改回来困难重重”。因此 Has 说,近似英语的外表“意外地鼓励了用户不切实际的想当然”。

如果你对 DSL 的可读性和表达力感兴趣,Dave 的博客文章上有更多的例子,评论也值得一看。

查看英文原文:Insights: You don't need your DSL to be English-like
架构语言 & 开发