2016-01-29

Internal DSL or External DSL?

DSL:
A domain-specific language (DSL) is a programming language that mimics the terms, idioms, and expressions used among experts in the targeted domain.


DSL优势:

Encapsulation

A DSL hides implementation details and exposes only those abstractions relevant to the domain.
Productivity
Because implementation details are encapsulated, a DSL optimizes the effort re quired to write or modify code for application features.

Communication
A DSL helps developers understand the domain and domain experts to verify that the implementation meets the requirements. A domain expert with little experience in programming can read, understand, and validate this code




DSL劣势:

DSLs are difficult to create
Although writing a DSL is “cool,” the effort shouldn’t be underestimated. First, the implementation techniques can be nontrivial (see the following example). Second, good DSLs are harder to design than traditional APIs.

DSLs are hard to maintain
DSLs can require more maintenance over the long term as the domain changes, because of the nontrivial implementation techniques used.  Implementation simplicity is often sacrificed for a better user experience.






Internal DSLs:
From Programming Scala


If the DSL is “close-enough” that it can be implemented internally with reasonable effort and ro bustness, the user experience will generally be better. It’s clearly the best choice for the test libraries mentioned earlier.


External DSLs:

 

The external DSL is simpler, but the user must embed the DSL in strings. Hence, code completion, refactoring, color coding, and other IDE features aren’t available.
If the DSL is too far removed from Scala syntax, perhaps because it’s a well-known language, like SQL, using an external DSL with quoted strings is probably best.




As a starting point for the discussion let’s take this definition from Martin Fowler “An internal DSL is just a particular idiom of writing code in the host language. So a Ruby internal DSL is Ruby code, just written in particular style which gives a more language-like feel. As such they are often called Fluent Interfaces or Embedded DSLs. An external DSL is a completely separate language that is parsed into data that the host language can understand”.

Erik started the controversy with this highly provocative statement:
I fully ascribe to Hudak-style embedded DSL, which really just are well-designed APIs. External DSLs on the other hand are like puppies, they all start out cute and happy, but without exception turn into vicious beasts as they grow up1 (make, XSLT, regular expressions, …).
and from there, all hell broke loose, with supporters of external DSLs claiming that better tool support in the shape of language workbenches made the statement untrue or at least made the cost of creating those DSLs acceptable
external DSLs are ugly: I think they are, but so are death and taxes
while internal DSLs fans discredited the tool support argument by saying that this was only a small part of the problem.

External DSLs … have no mother language to depend upon, and so they must reinvent much general purpose behavior.



使用内部还是外部DSL?

if ( 领域概念清晰 and  领域概念数目可控  ) {  //可尝试采用DSL
      if ( 目标DSL的代码量大 and 表达复杂度高 ) {
            //建议采用内部DSL            
            //1.  可借助编程语言本身的 图灵可计算性 来提升DSL能力            
            //2.  写DSL表达业务时,可借助编译器对语法正确与否的判断提示
            //3.  重构DSL时,可借助IDE的重构功能, 因为内部DSL本身就是正常的代码
          
     else  if ( 想突破编程语言语法限制,使用更符合领域的表达 ) {
            //采用外部DSL     
      }

else {
      //领域经常变化,会加大DSL维护成本
}



参考书箱 Programming Scala