Computational Reflection

    80年代,Brian Smith在《Procedural Reflection》中将“反射”这一概念提到了前所未有的高度。在他的这篇博士论文中,给出了在程序设计语言中实现反射这一机制的通用方法。使用过高级语言的程序员们一定不会对反射概念陌生。如今多数通俗的读物上都是这么描述反射的“反射是一种让程序(或者计算)能够检查和改变自我的机制”。这样的理解确实通俗易懂,却很难让人体会反射真正的机理。想要深入了解反射就必须从抽象机制和本源论这两件事儿说起。

抽象 vs. 反射

    我们先来说说抽象,在计算世界(或者说在Brian Smith的形而上学世界)里,概念总是分层而居的。一种底层概念通过抽象产生一种高层概念,随之建立起更高一层的抽象世界。底层概念是高层概念的原概念(meta),实现这些高层的概念。而高层概念抽象或者说隐藏了底层概念。这种分层的机制有一个好处,就是当人们通过某一层概念来水平的将现实世界映射到计算世界(或者说形而上学的世界)的时候,仅仅与该层抽象世界中的概念打交道即可。

    反射想要解决的问题是能不能在一个高层概念中访问实现高层概念的底层概念。因为高层概念隐藏了底层概念,所以只有通过扩展高层概念才能实现这个目标。Brian的方法是在高层概念中加入一个映射,将底层概念中涉及实现高层概念的部分映射到高层概念的抽象世界中。即在高层概念中对构成高层概念的底层概念建模。这一映射不要紧,要紧的是高层概念拥有了抽象自己的能力。这就是检查和改变自我的反射机制的前提。

    抽象和反射的概念广泛的适用与计算领域,其中一个就是计算机程序设计语言。一种语言由另一种更加底层的语言实现,高层的语言抽象掉底层语言的细节。反射在高层语言中构建了一个高层语言自身的模型,使得程序员操作这种自我的表示的模型等同于使用底层语言来操作高层语言的实现。

3-Lisp和反射塔

    在Brian的论文中,实现了一种叫3-lisp的支持反射的Lisp方言。该实现包含一个无穷嵌套调用的元循环解析器(infinite tower of metacircular interpreter),解析器由自身能够解析的语言实现(看过SICP的程序员们应该了解metacircular解析器是什么)。每一个解析器工作在与自身相同的解析器之上(高层抽象和底层抽象完全相同,这样就形成了无穷的塔状的循环抽象。) ,这种实现反射的模型,叫做Tower Model。Tower Model解决了一些由反射引起的问题,如反射可能造成计算停留在底层抽象而无法回到高层(好像卡在了meta层,看过黑客帝国的程序员们应该就能理解), 或者需要多层的Reflection的问题。

   反射塔营造出来的一种感觉是抽象就是抽象本身。

实现反射

    说了这么多,还有个很重要的东西没有讲。就是到底实现反射语言的通用方法是什么?

    在《Procedural Reflection》中,Brian将反射分为了两种,Structural Reflection结构反射和Procedural Reflection过程反射。前者能够让高层语言了解自身的语言元素,并且修改自身的程序代码(即程序就是数据),比如自己都有哪些类型、自己的代码是什么样的。后者则让高层语言能够动态的修改自己的计算过程(将计算过程当作一级对象),比如在计算的过程中将一部分计算过程替换成另一个计算过程。


-  要实现Structural Reflection,有两件事情要做, 

   1. 对自身的语言元素建模,并且提供操作这些元素的方法。

       这至少包括了up/down两种基本操作,up又可叫做reflection(狭义),是将高层的语言元素转变成底层的(meta层)语言表示。

        而down又叫做reification,是将底层的(meta层)表示转换成高层的语言元素。

       (因为Brian在论文中是以一种叫做3-lisp的语言作为反射实现的高层语言,所以如果你熟悉Lisp语言。

           也许你能够比较好的理解上面的两个操作,up类似于Lisp中的quote, down类似于Lisp中的eval。)


   2. 能够将自身的语言元素保存。

      (这个在Lisp里也是quote。)


-  要实现Procedural Reflection,就必须实现一种叫做Reflective procedure的反射型函数。该函数接受三个参数,函数体工作在低一层的语言层上。函数体接受的参数是其函数调用后面的参数的reification以及当时的环境、当时的计算流程。因为这种函数能够在计算过程中获取计算过程中用到的元素(如环境、计算流程)等,改变原有的过程就是很容易的事情。

    (作为对比,现如今的Lisp中,大部分仅仅实现了部分Procedural Reflection。比如Scheme中支持Continuation作为一级语言元素、部分Lisp支持将Environment作为一级元素。)

结语

    反射作为一种重要的程序设计语言的概念,在原编程、程序语言设计、解析器/编译器/调试器设计和实现等领域有着重要的地位。也是如今计算科学还热门的研究领域。

    看到这里还没有逃走的没有拍砖的程序员们,感谢你们的支持。本人学识尚浅,理解能力其实也不是太好。这里仅仅是将看到的东西以自己的理解总结于此。

引用


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值