• 推荐
  • 评论
  • 收藏

元编程

2022-11-04    5592次浏览

动态语言的另一个关键和有趣之处在于“元编程”。“元编程”实际上是“代码生成”的一种别称,其实在日常应用中我们也经常依赖这种做法。观察动态语言适合元编程的原因也是件十分有趣的事情。

在这个蓝框中是一段Ruby on Rails代码(见上图)。简单地说,这里定义了一个Order类,继承了ActiveRecord,也定义了一些关系,如belongs_to和has_many关系。Ruby这种动态语言的关键之处,在于一切事物都是通过执行而得到的,包括类型声明。比如这里的类型申明执行了belongs_to和has_many方法的调用,执行belongs_to会截获一对多或一对一关系所需要的信息,因此在这里语言是在运行的时候,动态为自身生成了代码。

实现这点在动态语言里自然会更容易一些,因为它们没有编译期和执行期的区别。静态类型语言在这方面会比较困难。例如在C#或Java里使用ORM时,传统的做法是让代码生成器去观察数据库,生成一大堆代码,然后再编译,有些复杂。不过我时常想着去改善这一点。

其中一种做法,是我们正在努力实现的“编译器即服务”,我现在先对它进行一些简单的介绍。传统的编译器像是一个黑盒,你在一端输入代码,而另一端便会生成.NET程序集或是对象代码等等。而这个黑盒却很神秘,你目前很难参与或理解它的工作。

你可以想象,一些代码往往是不包含在源文件中的。如果你想要交互式编程的体验,例如一个交互式的提示符,那么代码不是保存在源文件中而是由用户输入的。如果您在实现一个DSL,例如Windows Workflow或是Biztalk,则可能用C#或VB实现了一些需要动态执行的规则,它们也不是保存在源文件中,而可能是放在XML属性中的。此时你想编译它们却做不到,你还是要把它们放入源文件,这就变的复杂了。

另一方面,对于编译器来说,我们不一定需要它生成程序集,有时候需要的是一些树状的表现形式。例如一些由用户反射生成的代码,便可能不要程序集而是一个解析树,然后可以对它进行识别和重写。因此,我们可能越来越需要的是一些API,以此开放编译器的功能。

例如,你可以给它一小段代码,让它返回一段可执行的程序,或是一个可以识别或重写的解析树。这么做可以让静态类型语言获得许多有用的功能,例如元编程,以及可操作的完整的对象模型等等。我们正在朝这方面努力,我也会在下午1点的C# 4.0演讲中谈论更多这方面的内容。

相关文章

原文地址:https://www.cnblogs.com/Leo_wl/p/1971353.html