BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

思考:DSL用不着像英语

| 作者 Sadek Drobi 关注 0 他的粉丝 ,译者 郭晓刚 关注 0 他的粉丝 发布于 2008年4月9日. 估计阅读时间: 6 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

很多人都认为好的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

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

严重同意 by Xiang Ran

现在DSL真的都被吵的热过头了,很多技术盲从者已经不分就里的乱去布道概念,甚至自个压根也没想清楚到底怎么回事。典型的就是对DSL的好坏判断,‘越接近英文(自然语言)越好’之类的说法都要成主流的。

可是我从来都不觉得DSL一定要尽量的English,原因正如Dave所说滴那样子,DSL本来就是Domain Specific Language,本来就是种Language,而English就是English,压根就两码事。只不过可能一般的领域内的行话种夹杂了不少的自然语言,譬如常用的一些什么动词之类的,所以给很多人造成了误觉。
如何设计的DSL的根本原则就是问你要设计这个DSL所面向的领域的专家,他们想要如何才能清楚,明白,简单无误的表达他们想要的东西,这才是根本,这些永远都是需要调查的,而不是想当然的一味追求English-like...

这篇短文很好,期待也能来一篇《Agile用不着什么都包括》,感觉Agile是比DSL吵的更过头的buzzword了,也需要上上课了,别啥都跟Agile扯~~~~

说的不错 by Lee John

第一次接触rails的人,大都被它的表达能力所折服,但是我们应该想一想我们真正的目的是什么。
任何技术,它的最终目的只有一个──提高生产率(或者更广泛的说──投资回报率),为了达到这个目的,软件开发的输出物需要易于理解以便降低维护成本,需要表意清晰以降低协作成本,需要代码精练以降低编写成本,需要模块清晰以降低测试与集成成本。
这些才是我们的目的,从这些目的中,我们看不出自然语言有什么优势。
如果较真的话,自然语言倒是属于通用语言的范畴,而DSL的一大优势就是通过domain spec的方式简化了语言,我们何必一方面抛弃标准精确的计算机通用语言,一方面又拾起表意模糊、不够精确的自然通用语言呢。

Re: 说的不错 by 冯 希顺

如果DSL的发展方向不朝向自然语言,那么你发明越多、越高效的DSL,那么模块之间的协调性就越差,实际上就是发明了越来越多的方言,方言多了对于特定领域(范围很小)来说是高效的,对于协同作业来说那是相当低效了。比如SQL,对于数据库领域高效吧?但是这么多年大家在其他语言中(比如Java、C等等)为了理解SQL或者让SQL理解花费了多少代价?还有比如Unix命令,也简洁而高效吧?可是对于不懂这门方言的人来说,熟悉它有多困难?

当然现阶段自然语言还是不可能的,但是我觉得DSL的发展方向应该是朝向自然语言的。只有这样才不会出现巴比伦塔的灾难。不过,其实自然语言也是有无数方言的,业已发生过的、为了克服自然语言的方言所付出的代价难道以后还要在DSL中重演吗?

Re: 说的不错 by Xiang Ran

真服了,DSL是设计来给谁用的?领域专家,不是搞集成,协调什么的开发人员。

拿SQL做例子,SQL可以说是最成功的DSL了吧,都早于DSL这个词出现之前N久。

如果SQL不好为什么竟然变成的DB的标准,为什么不是 select anything in ... 而是 select *,多么的简洁明了而又恰到好处的表达了含意呢?

甚至连数学里面的各种符号,为什么要发明那么多符号,而不是直接用单词来描述,就是因为符号一旦成为一种约定,一旦被学习理解,在长期的使用中是最明显提高效率的,因为这些符号具有含义唯一性,确定性,同时大多情况又比自然语言简洁这些特性。

至于你说协调问题,那又是另一个问题了,比如一个没有SQL基础,只有OO概念和学过JAVA的人来说,当然他写SQL痛苦了嘛,就跟非数学专业的人看专业的数学书中的式子一样嘛。你就不是搞这个的,你当然不明白了,所以觉得痛苦了。但是当然,为了开发效率和综合成本,总不能一定雇到精通SQL又懂java的人吧,所以那不是就出现了Hibernate么,Hibernate才是解决这种问题的一种方案。但是这并不能说是SQL自身的问题,并不是说DB的借口应该像Hibernate那样提供OOP的类的封装借口类似的API啊。


自然语言为啥不是DSL的方向,因为自然语言是给人打交道用的,DSL是给机器理解的,人脑和机器压根不一条路子。所以自然语言这种具有很多模糊,不精准,需要结合上下文判断的Language无法让领域专家轻易的向计算机说清楚他们要表达的东西。但你看数学和计算机结合多紧密,因为1+1这不也是数学中的DSL嘛,有着清晰的含义的符号,你只要告诉计算机这些符号的运算规则,计算机就知道结果就是2了呗^_^

Re: 说的不错 by Guo Xiaogang

越精确、简练,越容易翻译成其他语言。

Re: 说的不错 by 冯 希顺

我觉得SQL之所以成功有部分原因是由于SQL其实挺像自然语言的,呵呵。

开发软件的过程实际上是一系列的翻译过程,一开始,用户将需求描述给需求分析人员(自然语言),需求分析人员将用户需求传达给架构师或者设计师(自然语言),设计师使用UML之类的建模语言(领域语言)创建软件架构,开发人员将UML翻译成Java或者其他什么语言(领域语言)。为了高效使用数据库,部分操作需要在SQL和Java语言之间翻译,为了灵活性,部分配置信息需要使用XML保存起来,为了UI,需要使用HTML之类的语言呈现给客户。那么在这个过程中经历了多少语言翻译过程?虽然计算机语言之间翻译相对于自然语言翻译要简单的多,但是同样无法自动进行。

DSL的朝向如果不是自然语言的话,那么DSL对于解决现实问题不会有多少作用的,可以说DSL最后的走向就是死胡同。当然,如果DSL是为了加大竞争者进入的难度,这样做倒是可以理解。另外,其实我觉得英语不适合作为DSL的目标,因为英语的发散性太厉害了,实际上现在英语就已经有很多领域语言了(据说医学书籍对于外行来说几乎完全无法理解了)。我倒是觉得汉语是不错的DSL的方向,哈哈。最后说一句,如果不是为了解决Java语言和SQL语言之间的DSL的翻译问题,鬼才愿意使用这种纠集了Java/XML/SQL和一个叫HQL的大杂烩的。

逻辑混乱 by Guo Xiaogang


虽然计算机语言之间翻译相对于自然语言翻译要简单的多,但是同样无法自动进行。DSL的朝向如果不是自然语言的话,那么DSL对于解决现实问题不会有多少作用的,可以说DSL最后的走向就是死胡同。

我就不明白你的DSL是要解决什么现实问题了。你自己都认同计算机语言比自然语言容易翻译,那为何要向难翻译的自然语言靠拢。

实际上现在英语就已经有很多领域语言了(据说医学书籍对于外行来说几乎完全无法理解了)。

自然语言尚且分化成DSL,DSL为何要走回头路?

Re: 逻辑混乱 by 冯 希顺


我就不明白你的DSL是要解决什么现实问题了。你自己都认同计算机语言比自然语言容易翻译,那为何要向难翻译的自然语言靠拢。

计算机语言是容易翻译,但是针对不同的领域你要发明多少种DSL?X方向的有不同的业务领域(医疗、保险、银行等)、Y方向有不同的技术领域(数据库、UI、工作流等)、Z方向还有不同的自然语言领域(汉语、英语、日语等)!沟通和交流(不仅仅是人类之间,也包括各种DSL之间)要花多少代价你不是不清楚吧?又有多少问题是由于这种沟通和交流问题引起的你也不会不知道吧?

自然语言尚且分化成DSL,DSL为何要走回头路?

就因为自然语言分化成DSL后花费了太多的代价,所以DSL才要走你说的“回头路”。

Re: 逻辑混乱 by Guo Xiaogang

那你岂不是假设存在一个语言能解决所有问题。
自然语言分化成DSL不正是说明你的假设太虚幻。

Re: 逻辑混乱 by 冯 希顺

那你岂不是假设存在一个语言能解决所有问题。
自然语言分化成DSL不正是说明你的假设太虚幻。


我不是说要用一种DSL解决所有问题,我只是说DSL应该朝向自然语言方向发展。就现在来说,其实所有的计算机语言都是基于英语的DSL。如果DSL发展不朝向英语,现在已经这么多问题了,将来的问题就会更多了。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

10 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT