黄健宏对《DSLs in Action》的笔记(10)

DSLs in Action
  • 书名: DSLs in Action
  • 作者: Debasish Ghosh
  • 页数: 375
  • 出版社: Manning Publications
  • 出版年: 2010-12-28
  • 第4页

    每个程序都是一个从问题领域映射到解决方案领域的实现。

    Every application that you design maps a problem domain to the implementation model of a solution domain.
    引自第4页

    问题领域以及领域建模

    In a domain modeling activity, the problem domain is the processes, entities, and constraints that are part of the business that you’re analyzing. Domain modeling, also known as domain analysis (see [1] in section 1.9), involves the identification of all the major components of the domain and how they collaborate.
    引自第4页

    解决方案领域

    You implement a problem domain analysis model in terms of the tools and techniques offered by the solution domain.
    引自第4页
    2011-12-11 23:42:13 回应
  • 第10页

    DSL 的定义

    A DSL is a programming language that’s targeted at a specific problem; other programming languages that you use are more general purpose. It contains the syntax and semantics that model concepts at the same level of abstraction that the problem domain offers. Programs that you write using a DSL must have all the qualities that you expect to find in a program that you write in any other computer language. A DSL needs to give youthe ability to design abstractions that form part of the domain. In the same way that you can build a larger entity out of many smaller ones in the problem domain, a well-designed DSL gives you that flexibility of composition in the solution domain. You should be able to compose DSL abstractions just like you compose your functionalities in the problem domain.
    引自第10页
    2011-12-12 00:15:37 回应
  • 第11页

    DSL 和 GENERAL-PURPOSE PROGRAMMING LANGUAGE 不同的地方。 最重要的两点:

    A DSL is targeted at a specific problem area A DSL contains syntax and semantics that model concepts at the same level of abstraction as the problem domain does
    引自第11页

    使用 DSL 的好处:

    When you program using a DSL, you deal only with the complexity of the problem domain. You don’t have to worry about the implementation details or other non-essential elements of the solution domain.
    引自第11页

    使用 DSL 的例子:

    More often than not, people who aren’t expert programmers can use DSLs—if the DSL has the appropriate level of abstraction. Mathematicians can easily learn and work with Mathematica, UI designers feel comfortable writing HTML, hardware designers use VHDL (very-high-speed integrated circuit hardware description language; a DSL used in electronic design automation) to name a few such use cases.
    引自第11页

    DSL 不仅是一种程序,它还是和业务人员沟通的工具:

    The key issue is communication, the ability for your program to communicate with its intended audience. In the case of a DSL, the direct audience is neither the compiler nor the CPU, but the human minds that need to understand its behavior.
    引自第11页

    DSL 的实现要求/目标:

    The DSL that you design has to offer the correct level of syntactic as well as semantic abstractions to the user.
    引自第11页
    2011-12-12 11:56:41 回应
  • 第14页

    怎样写一个好的 DSL ? 恰当的抽象层次,面向用户的API,隐藏实现细节。

    A DSL provides a direct mapping to the artifacts of the problem domain. If the problem domain has an entity named Trade, the DSL script must contain the same abstraction that plays the same role.
    引自第14页
    The DSL script must use the common vocabulary of the problem domain. The vocabulary becomes the catalyst for better communication between developers and business users. When business users interact with the software domain model, the DSL script is their interface, as shown in figure 1.3.
    引自第14页
    The DSL script must abstract the underlying implementation. This principle is an important part of good abstraction design, and it applies to DSLs as well. The DSL script cannot contain accidental complexities that deal with implementation details.
    引自第14页
    2011-12-12 12:30:05 回应
  • 第15页

    DSL 的本质,创建元语言抽象,或者更直接地说,创建一种新语言。

    In most cases, a DSL is nothing but a layer of abstraction over the host language that presents a domain-friendly interface to the business users. (It’s not always the host language. See section 1.5 for details about DSL classification.) You’re kind of extending the host language to implement another language on top of it. This concept is sometimes referred to as a metalinguistic abstraction.
    引自第15页
    2011-12-12 12:41:29 回应
  • 第16页

    DSL 执行的几种模式: 1. 作为 script 直接运行(比如 AWK) 2. 作为 bytecodes 在 VM 之上运行(比如 JAVA 系的DSL) 3. 作为编译器时的元语言运行(比如 Lisp)

    The script can directly execute the underlying model without any more code generation or manipulation. There might be an interpreter that directly interprets the script and runs it. The UNIX little programming languages awk and sed are examples of DSLs that execute directly.
    引自第16页
    A DSL script that’s developed on a virtual machine follows the second model. The semantic model underlying any Java DSL script generates bytecodes that are executed on the JVM.
    引自第16页
    Some languages offer compile-time metaprogramming. When you’re developing a DSL using this kind of language, you build metastructures as part of your source code, which get translated to the normal forms of the language before it runs. Lisp supports this technique through macros that get expanded to normal Lisp forms during the macro expansion phase (I discuss this in more detail in appendix B). For these languages, there’s an intermediate stage where you have source code translation before the byte code is generated for the virtual machine.
    引自第16页
    2011-12-12 12:52:01 回应
  • 第18页

    Internal DSL 的定义:

    An internal DSL is one that uses the infrastructure of an existing programming language (also called the host language of the DSL) to build domain-specific semantics on top of it. In most cases, an internal DSL is implemented as a library on top of the existing host language. As you see in figure 1.5, the internal DSL script is a thin veneer over the abstrac- tions of an underlying host language.
    引自第18页

    External DSL 的定义:

    An external DSL is one that’s developed ground-up and has separate infrastructure for lexical analysis, parsing techniques, interpretation, compilation, and code generation. Developing an external DSL is similar to implementing a new language from scratch with its own syntax and semantics. Build tools like make, parser generators like YACC, and lexical analysis tools like LEX are examples of popular external DSLs. Of course, the complexity of an external DSL implementation depends on how rich you want it to be.
    引自第18页
    2011-12-12 14:51:47 回应
  • 第37页

    Internal DSL 主要分为两种类型:

    Generative—Domain-specific constructs are transformed to generate code through compile-time macros, preprocessors, or some form of runtime meta-object protocol (MOP). Embedded—Domain-specific types are embedded within the type system of the host language.
    引自第37页

    这两种类型并不是互斥的,比如一个 Lisp 宏写的 Internal DSL 就是两种兼有。 实现 Internal DSL 时经常用到的一些技术:

    『SMART API』 一般是 Builder 模式和 fluent interface 模式的混合体,用单个对象串联起多个方法,形成一个方法链。 例子: Customer.name("huangz").buy(2).apple() 缺点:滥用方法,比如上例在一些更高级的语言中就可以写成 CUstomer( :name "huangz" :buy 2 :item apple),不用串联方法那么麻烦。 『SYNTAX TREE MANIPULATION』 构建语法树,并在语法树之上进行操作。 例子: Lisp 的宏 『TYPED EMBEDDING』 在 host language 之上构建新类型,增加抽象层次。 例子: Haskell 的 Monads 『REFLECTIVE METAPROGRAMMING』 利用语言提供的一些 API ,实现一些特殊功能。 例子:《Metaprogramming Ruby》(中文版:《Ruby元编程》)这本书有很多这类例子 『RUNTIME METAPROGRAMMING』 在程序被运行时生成一些代码。 例子: 在 Rails 中通过 ActiveRecord 生成 Table 代码。 『COMPILE-TIME METAPROGRAMMING』 在程序被编译时生成一些代码。 例子:Lisp 的宏。 运行时元编程和编译时元编程的区别

    2011-12-13 00:04:18 回应
  • 第45页

    External DSL ,其实就是写编译器/解释器。 不过 DSL 的语法比一般的编程语言少很多,满足基本需求就可以,甚至不必是图灵完备的。

    External DSL design follows the same lifecycle and principles of general-purpose language design. Although the statement is true in theory, it’s not all that grim when you consider that your DSL isn’t necessarily as complex in syntax and semantics as a general-purpose programming language can be. In reality, you can process some external DSLs by manipulating strings using regular expressions. But the only common trait of all external DSLs is that they aren’t implemented using the infrastructure of a host language.
    引自第45页

    External DSL 的两个主要步骤:

    Parse—where you tokenize the text and use a parser to recognize valid inputs Process—where you do the business processing on valid inputs that were recognized by the parser in the first phase
    引自第45页

    写 External DSL 时常用到的技术:

    『CONTEXT-DRIVEN STRING MANIPULATION』 解释文本,生成代码。 『TRANSFORMING XML TO A CONSUMABLE RESOURCE』 解释 XML ,生成代码。 『DSL WORKBENCH』 这个其实不是技术,而是一些帮助你写 External DSL 的工具。 『MIXING DSL WITH EMBEDDED FOREIGN CODE』 利用 YACC 和 ANTLR 等工具按照规则生成 DSL ,这些 DSL 运行在其他语言之上。 『DSL DESIGN BASED ON PARSER COMBINATORS』 MIXING DSL WITH EMBEDDED FOREIGN CODE 技术的加强版。

    2011-12-13 00:55:30 回应
  • 第55页

    开发 DSL 时主要考虑的三件事:

    Integration issues Handling exceptions and errors Managing performance
    引自第55页

    关于集成需要注意的问题: (Internal DSL Integration)

    (External DSL Integration)

    异常和错误的处理问题:

    性能问题: (略过)

    2011-12-13 11:53:11 1人喜欢 回应