DSL 思考

一、什么是DSL

DSL,即Domain Specific Language,是为在某些特定领域内解决特定问题而设计的专用语言,其基本思想是“求专不求全”。DSL主要目的是消除代码复杂度和间接性,并且应该注重专业领域。此外,也需要合理恰当的语法形式来实现DSL。

DSL 的类型:

  • 非计算

    HTML、CSS

  • 计算能力有限

    SQL、 CPP templates 、正则表达式

  • 异构

    GLSL

  • 特殊应用

    Matlab

二、 Embedded DSL

Embedded domain-specific language(eDSL)是嵌入式DSL,其优势是利用宿主语言实现。嵌入式DSL可以看做是库,API can usefully be thought of as a language

Embedding DSL 利用宿主语言的现有api实现,不再需要编写解析器。

实现 eDSL 的方式有如下几种:

  • 字符串

    是最简单的实现方式,因为不需要编写解析器。最好的例子是在JQuery中检索CSS

    1
    const myTable = $("#foo div.tabular-data table);

    CSS选择器是只是指定一组HTML document 元素的DSL。

    同样,还有正则表达式。

    1
    const matches = input.match(".*/.+\\.png$");
  • 宏定义、准引用(Quasiquotation)

    宏定义(Macros)能够在编译时期执行代码。宏常常与准引用一起使用,比如在Lisp和 Haskell 中可以自定义语法。

    在Yesod 网络框架中,Haskell 有 Shakespearean Templates 的例子,允许HTML/CSS/JS代码在Haskell 代码中插值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    data Person = Person
    { name :: String
    , age :: Int
    }

    main :: IO ()
    main = putStrLn $ renderHtml [shamlet|
    <p>Hello, my name is #{name person} and I am #{show $ age person}.
    <p>
    Let's do some funny stuff with my name: #
    <b>#{sort $ map toLower (name person)}
    <p>Oh, and in 5 years I'll be #{show ((+) 5 (age person))} years old.
    |]
    where
    person = Person "Michael" 26
  • 组合Combinators

    Combinators 是利用小函数或者对象进行构建,因为没有自定义语法,所以很像 API。

    例如,Ruby的Rake构建系统对.md文件运行pandoc生成.html文件。

    1
    2
    3
    4
    5
    6
    task :default => :html
    task :html => %W[ch1.html ch2.html ch3.html]

    rule ".html" => ".md" do |t|
    sh "pandoc -o #{http://t.name} #{t.source}"
    end
  • Monads

    在Haskell 中可以利用 Monad 来实现 eDSL。

    1
    2
    3
    4
    5
    result = do a <- [1..10]
    b <- [1..10]
    guard (a /= b)
    guard (a + b == 7)
    return (a, b)

eDSL 因为能够用于处理专用领域中的问题,所以用处极大。但是在DSL设计和使用中,应该注重在实现上使用恰当的语法。同时,对于DSL解决的问题可能是“动态逻辑加载”,可以使用现有语言动态调用解析器来完成。

库(library)和 eDSL 很相似,有时候最简单的库就能够解决问题。

Embedded DSLs are useful because they let us apply everything we know about programming languages to specific domains.

参考

  1. What is an embedded domain-specific language?

  2. 王垠——DSL

  3. Embedded Domain Specific Language

  4. 领域专用语言迷思

  5. DSL在实际工作中的应用

作者

Hu

发布于

2018-07-17

更新于

2018-07-17

许可协议

评论