您的位置:首页 >> 编程开发 >> .NET >> C# >> 正文
C# RSS
 

在CLR之上的构建领域特定语言

http://www.rdxx.com 08年10月10日 00:00 我要投稿

关键词: 语言

  最近领域特定语言(DSL,Domain Specific Languages)这个话题比较热门。这可以从Rails现象中看到。Rails的流行以及Rails上广泛使用的领域特定语言(从现在起叫DSL),已经引起了对DSL的广泛兴趣。
 
  到现在为止开发人员有这样的印象,建立一个DSL,你需要专业的编译器理论知识,理解Lex和Yacc的内部工作原理并需要投入大量的时间来构建DSL.结果是极少数人愿意去尝试,他们都是从头开始构建自己的语言。
 
  这往往是成本高昂。
 
  同时,动态语言的爱好者可以毫不费力的利用他们喜欢的动态语言的动态特性来构建领域特定语言。事实上,他们中的许多以这种方式构建的任何应用程序,都有着显着的复杂性。
 
  这两种方法的差别有重要意义。第一种方式是创建属于自己的语言,就是所谓外部的DSL(External DSL)。这是一个耗资巨大的项目,因为一切都要从头开始构建,需要考虑运算符的优先级规则、运行时类库、执行代码、错误处理和I/O.第二种方法是利用和修改宿主语言,就是所谓内部的DSL(Internal DSL)。这些都容易构建和维护。你只需要考虑如何修改,所有的其它东西(通常是你不用关心的)都已经被宿主语言处理了。
 
  另一种做法是构建连贯接口(Fluent Interface),把它叫做DSL.我认为这不是一种DSL,这种方法往往在语言的自由性方面受到很大的限制。JavaC#就是很好的例子,包括 Java 6和C# 3.你可以列举许多语言方面的API,但这不能让我觉得这是一个DSL.在任何情况下,我的个人偏好是使用具有很高语法灵活性的内部DSL.因为我基本上都是在CLR上工作,我想利用运行在这个平台上的宿主语言。它可以让我重用大部分的使用CLR的知识,不要低估这方面的好处。在你的手中有一个熟悉的环境是非常重要的。
 
  在深入语言之前,看看究竟什么是“高语法灵活性的语言”,怎么样?为内部DSL提供一个良好的宿主环境的语言需要具有哪些特性?
 
  我需要有合适的手段来表达我的想法。这可以通过有启发性的命名,表达特定域的概念,并通常和通用语言的做法不一样。你希望能够创建一个第四代语言,这很容易做到。让我们从一个我们电子表格所使用的脚本这样简单的DSL开始如何?
 
  你的任务就是创建乘法网格。
 

for x in range(100):     for y in range(100):         

cell[ x+1 , y+1 ]  = x * y    

formula x, 100, sum( x1, x100 )

  这是不是真的令人印象深刻呢?这和编程语言几乎完全一样,代码也是微不足道。除了和用Excel的自动化API做一样的工作外,更简短。
 
  注意到这就是我们所用到的所有代码。我们不需要一个类的定义,或者是一个主方法。这是一个没有任何语法包袱的可执行的DSL脚本。
 
  如果前面的例子没有给你留下深刻的印象,看看如何定义订单折扣的业务规则:

apply_discount_of 5.percent:        

when order.Total > 1000 and customer.IsPreferred        

when order.Total > 10000suggest_registered_to_preferred:        

when order.Total  > 100 and not customer.IsPreferred


  这看起来和编程语言有很大不同,它更像业务分析师在Word文档中定义的业务规则。
 
  从我的角度来看,上面两个例子都是领域特定语言。他们只是表达领域的方法和风格不同。这两个例子,我们实际上已经从语言中移除了和我们的领域没有直接关系的东西。这使得我们可以专注于域,并希望有良好的工具来处理。
 
  除了域概念以外,没有任何东西可以和具有与域相匹配的语法是一样重要的。
 
  当我们开始在CLR上研究高语法灵活性的语言的时候,我们有很多的选择。我们来评估几个语言。我们将从几个来自微软的语言开始。
 
  C# —— 这是一个非常刚性的语言,类型定义,没有独立的方法/代码块,僵硬的语言。所有这些特性使得C#不是一个DSL宿主语言的好选择。他也可以做到的,但它不如其他方法。
 
  VB.Net —— 其实VB.Net更适合面向对象的语言,因为它使用了许多英文单词作为关键字和操作符。令人遗憾的是它也是一个非常冗长的语言,我们要减少冗余性适合我们的域概念。
 
  JScript —— 这可能引来一片笑声,但是JScript是一个非常灵活的语言,为许多事情提供了较好的语法。只要去看看所提供的所有Javascript类库。JScript提供了和Javascript相同的基础功能。虽然这样,有一点不得不考虑的是你可以做到像JQuery或 Prototype那样多大的灵活性。然而它不够成熟,我不确定将来是什么样子的。虽然它在很多方面有灵活的语法,给人有种编程语言的感觉,这会让我在一个DSL中觉得分心。
 

  F# —— 这是一门由微软开发的,将来会发布的函数式编程语言。F#支持面向对象编程。我已经简略的浏览过这门语言。虽然F#的强大功能令人印象深刻,从我的角度来看,它看起来是BNF「译者注:BNF, Backus-Naur Form的缩写,巴科斯范式一种使用形式化符号来描述给定语言的语法。」定义,其他什么都不像。毫无疑问这是由于作者缺乏函数式编程语言经验方面的问题,但是我不只是考虑它的可读性。
 
  我们已经看完微软开发的语言。让我们看得更远些。据统计去年CLR上运行的语言超过了一百种,所以我选择了两种我认为是DSL宿主语言的候选语言。
 
  Nemerle是一个多范型的语言(面向对象和函数式),完全支持编译器宏(后来更多的是Lisp的变种,而不是C++),以及许多其他的东西,这使得它是一个DSL很好的宿主语言。这不是我阅读Nemerle代码的简单理由(经常是这样)。
 
  Boo是一个基于Python语法的静态类型的面向对象的语言。它支持宏(也是Lisp变种),有一个开放的编译器管道和更容易构建DSL的特性。Boo是我首选的用于构建DSLs的语言,但是为了保证客观性,我们需要在讨论这个主题之前证明Boo有多么的强大。
 
  动态语言运行时(DLR)怎么样呢?
 
  到目前为止我还没有讨论动态语言运行时,这是一个在CLR之上支持动态语言的微软项目(目前支持Ruby,Python和EcmaScript)。
 
  更具体的来说,当人们讨论DLR的时候,他们是在讨论IronRuby和IronPython. Ruby是一门被证明非常适合写内部DSL的语言,在CLR上运行可以使我们在熟悉的环境下工作。
 
  使用DLR作为一个DSL的平台当然是可能的,但是我至少在一段时间内不使用它。DLR和IronRuby本身都还是在开发之中。我不认为微软对发布日期会有任何的承诺,此外我没有发现Ruby能做的Boo做不了,我觉得Boo的元编程基础功能非常自然和强大。
 
  “自然和非常强大”是什么意思?
 
  让我们深入一点考查Boo.我说它有一个开放的编译器,我并不是指它是开放源代码的(它是,但是和这个无关),我的意思你有办法深入到编译器的内部和在编译的时候打乱编译器的内部对象模型。这意味着我们可以以一种有趣的方式改变编译器的行为。
 
  上面的两个代码示例都是Boo的DSL代码。
 
  全面深入Boo的元编程基础功能超出了本文的范围,但是我可以用一个简单的例子来展示它的威力。
 
  CLR已有IDisposable的概念并配合using语句使用。现在我定义一个ITransactionable,将用它来定义一个事务的声明。
 

public interface ITransactionable:    

def Dispose():        

pass    

def Commit(): 

pass    

def Rollback():        

passmacro transaction:     return [|        

tx as ITransactionable = $(transaction.Arguments[0])        

try:             

$(transaction.Body)             

tx.Commit()        

except:             

tx.Rollback()             

raise        

finally:             

tx.Dispse()    

|]

  只需要这个代码,我们就可以作为一个头等语言要素来使用该事务的声明了(实际上,这也正是using语句在Boo的实现方式)。
 
  transaction GetNewDatabaseTransaction():         DoSomethingWithTheDatabase()
 
  现在,如果代码里面的事务抛出了一个异常,事务将自动回滚。如果它执行是成功的,事务就自动提交。
 

共2页  第1页 第2页


 
 
标签: 语言 打印本文
 
 
  热点搜索
 
 
 



Valid XHTML 1.0 Transitional
Copyright ©2005 - 2008 Rdxx.Com,All Rights Reserved
收藏本页
收藏本站