DSL语言-Domain Specific Language

DSL又称领域特定语言,它是针对特定问题的计算机语言,而非针对软件问题的通用语言。

DSL如今非常普遍,如:CSS、正则表达式、make、rake、ant、SQL、HQL、many bits of Rails、JMock中的expectations,dot语言工具包Graphviz、FIT、struts配置文件等。

DSL

可能已经接触DSL很过年,但并未特别关注它。如果,曾编写过makefile或使用CSS设计过网页,那么,就已经见识过DSL了。

DSL是为特定任务定制化设计的小型富有表现力的编程语言,与Java之类的通用语言不同,DSL的表现力相当有限,它专注于某种类型的问题或针对某个领域,在有限范围内表达一组狭隘的解决方案。

这就是DSL的优点 -简洁明了。

设计良好的DSL,就像一道由大师烹饪的美食,既让人吃的爽又能均衡营养。

DSL设计应始终考虑不要让使用者担心它的语法问题,如:

matrixA.multiply(matrixB);

matrixA * matrixB

这两种表达方式孰优孰劣高下立判。

分类

DSL通常分为内部DSL(Internal DSLs)和外部DSL(external DSLs),这是一个重要的区别。

外部DSL设计独立于任何特定语言,外部DSL的设计者,可以使用任何语言和工具实现DSL。

内部DSL是使用宿主语言,在主流语言(如Java和C#)中也可以执行内部DSL。内部DSLs也被称为嵌入式DSLs或FluentInterfaces。

内部DSL采用宿主语言的语法,因此,不必花费时间或精力重写编译或解析。

外部DSL

外部DSLs有自己的语法,可编写一个完整的解析器处理它们。在Unix社区中有一个非常强大的传统。许多XML配置最终都成为外部DSLs,尽管XML的语法非常不适合这一目的。

外部DSL通常定义为使用单独语言编写,如:Unix小语言和XML配置文件就是这种风格的例子。

外部DSL关键优势在于可自由选择喜欢的形式。格式仅受限于构建翻译器的能力,翻译器可解析配置文件并生成可执行文件 - 通常采用擅长的语言。

一个明显的缺点是 - 必须构建一个翻译器。XML虽然限制了DSL的形式,但很容易解析。

与此相关的是DSL设计的困难度 - 语言设计很难,因此,设计多个DSL对于大多数项目来说太难了。

API设计和DSL设计之间的区别相当小 - 所以设计DSL并不比设计好的API困难多少,这种相反的意见源于习惯了通用语言而非DSL。

对于许多人而言,外部DSL的一大优势是能够在运行时评估DSL,这允许不对程序做重新编译的情况下修改参数,这是XML配置文件在Java世界中如此受欢迎的主要原因。

虽然这是静态编译语言的一个问题,但现在对混合编译和运行时语言也越来越流行,如.NET的IronPython,允许在大多数C#系统上下文中评估IronPython内部DSL。

这是Unix世界将C/C ++与脚本语言混合的常用技术。

内部DSL

内部DSL颠覆了外部DSL的优点和缺点。内部DSL更接近编程语言,使用内部DSL可降低工具成本 - 但由此产生的限制也大大降低了DSL的优势,特别在仅限于使用C语言的情况下,外部DSL实现优势有更大的潜力,但设计语言、构建翻译器及编程工具的成本也相当高。

DSL可通过解释或代码生成来实现,解释(读取DSL脚本并在运行时执行)通常是最简单的,但代码生成有时是必不可少的。通常,生成的代码就是语言自身,如Java或C。