DSL 边界
2006年8月1日
当谈到领域特定语言这个话题时,一个常见的困惑是究竟什么是或不是 DSL。问题在于 DSL 没有精确的定义,而且在 DSL 和其他事物之间存在很大的灰色地带。
对我来说,DSL 的一个关键要素是它们在范围(它们指的是特定领域)和能力(它们缺乏通用语言的基本功能)方面都受到限制。因此,好的 DSL 通常都很小很简单:因此被称为“小型语言”和“迷你语言”。
对于内部 DSL 来说,模糊的界限在于什么是 API,什么是 DSL。从根本上说,它们之间没有区别,内部 DSL 只是一个花哨名称的 API(正如贝尔实验室的老话所说:“库设计就是语言设计”)。然而,尽管如此,我认为在使用具有 DSL 风格的 API 时,感觉是不同的。像流畅接口这样的东西可以使使用 API 的体验在质量上有所不同。从 DSL 的角度思考会让你以不同的方式思考可读性,利用宿主语言的语法来创建一些看起来独立的东西 - rake就是一个很好的例子。
当谈到外部 DSL 时,问题通常以 DSL 和通用编程语言 (GPL) 之间有什么区别的形式出现。通常,一个明显的标志是 DSL 不是图灵完备的,或者缺乏抽象机制。正则表达式是这种能力限制的一个很好的例子。SQL 是一个更有趣的候选者。它是一种复杂且功能强大的语言,但缺乏图灵完备性和构建新抽象的能力。
一种语言可以是图灵完备的,但仍然是 DSL 吗?Ploticus的脚本语言是图灵完备的,但它明显侧重于在 Ploticus 中生成图表,这使得它成为一种 DSL——至少对我来说是这样。但是,那么 XSLT 呢?它也专注于转换 XML 文档,但它已经获得了如此多的功能,以至于越来越多的人将其视为一种 GPL。
Ploticus 的例子提出了一个问题,即嵌入式语言是否是 DSL。当 Excel 的宏语言实际上与 Visual Basic 相同时,它是一种 DSL 吗?如果将通用脚本语言嵌入到应用程序中会发生什么?
与内部 DSL 与 API 的问题一样,我认为关键在于意图,包括语言编写者和用户的意图。如果我只使用 XSLT 来转换 XML 文档,那么我就是在将其视为 DSL——即使我确实进行了一些花哨的调用以在输出文档中嵌入一些值。但是,如果我用它来解决八皇后问题,那么我就是在将其用作 GPL。如果 XSLT 的设计者将其视为关于 XML 转换的,那么他们就会将其视为 DSL,即使聪明的人用它做了一些不自然的事情。
这是一个在酒吧里讨论很有趣的话题,但不应 detract from 使用 DSL 的好主意。DSL 的设计应该像过去一样,是一种专注于单个问题的有限语言。如果你在设计和使用它们时始终牢记这一理念,它们就会很有用。毕竟,真正重要的是实用性。