解释Intentional Programming
——三种视角的视图
作者:taowen(mo2mo@163.com)摘要
本文的目的是用尽可能简明的语言记录下笔者对于Intentional Programming的初级认识,以把这激动人心的技术传播给更多人。但是限于理论发展的现状,资料的完备情况,以及最重要的,笔者的认知程度,并不能保证文中所记内容的准确性。概览
Intentional Programming是对传统编程语言的一种颠覆,因而是对编译原理,程序语言设计理论的一种颠覆,是管理复杂度技术的一种远景技术,对程序员乃至普通个人的编程体验的一种全新模式。
这就是我能给出的无内容概要。循此概要而去,我将从这三个角度来记录一些理解:1、 编译原理和程序语言设计理论
2、 管理复杂度的实践技术
3、 编程体验
意图编程的理论实质
意图编程对于传统的编译原理和程序语言的设计理论是一种颠覆。而意图编程是这样的
从图中可以看到,GUI的交互代替了文法解析。而我用蓝色标注意图编程的“代码生成”的目的是把它与上面的代码生成区别开来,因为两者的实现手段是完全不同的。因为在解析和代码生成两个阶段的巨大差异,所以我说意图编程对于传统的编译理论是一种颠覆。 具体来看一个例子就能说明两种过程之间的区别了,先来看传统的语言:
int x;
x = 1;
1、 C:
int x = 1;
以及
int myproc(int x, int y) {
return x + y;
}
变量和过程代表了其最明显的语言特征
2、 Java:
class myClass extends baseClass implements someInterface {
private int x;
public void setX(int x) {
this.x = x;
}
}
以及
myClass o = new myClass()
类和对象代表了其最明显的语言特征
3、 Scheme:
(define (max x y) (if (> x y) x y) )
以及
(max 2 3)
表结构代表了其最明显的语言特征
4、 Prolog:
Seq(Env, num(Val), Val).
Fact,term,rule等代表了其最明显的语言特征
从语法层次来看,这些语言特征的体现在AST(抽象语法树)的一些节点上。不同语言对于这些节点的语义解释构成了其独特的语言特征。本质上说,语言的特性,就是给AST的节点赋上的语义,而这种语义体现又完全体现在代码生成之中。 在意图编程中,这个过程是:
这里所说的意图库具体是什么在下面描述,这里所提供的语义是抽象意义上的,具体的实际表现就是意图库完全操控了从抽象语法树到目标代码的代码生成过程,在这个代码生成过程中体现了其语义,从而体现了一定的语言特征。 如此定义语义,定义语言特征,如此根据语言特征划分程序语言,可以得出一个意图编程包含面向过程∪面向对象∪泛函∪逻辑∪……的结论。
1、 怎么通过GUI来操作AST?
在这个问题上,有一个实际可用的实现。这个实现是易语言的集成开发环境,它就是通过GUI来操作AST,实现了无语法无文本源代码无解析的编程。 这是一段C的代码void someproc(int x) {
if (x==0) {
//do something
}
}
这是同样功能的易代码在GUI上的呈现这段代码的输入过程是这样的:
Ctrl+N
修改子程序名
修改返回值类型
添加函数参数——在someproc上按回车
和前面一样的方法,修改参数名和类型 然后添加一条语句
按回车之后,易语言的IDE就能自动把输入转化为最前面的那个形式。至于添加注释就属于细枝末节了。 而两者对应的AST,可能是一样的:
这里的GUI表现,让人的印象并不深刻。而且,我也不能说这里用GUI来表示和输入代码了,就完全没有语法了。因为数学表达式还是存在的。所以在局部还是需要语法解析的,不过这只是一种实现策略,如果比较极端一些,通过GUI的代码输入可以完全和文法无关。 无论易语言的IDE的GUI如何,至少通过这么一个实际例子证明了,AST的生成不是华山一条路。通过对具有文法结构的源代码文本进行解析(parse)是一条路,直接用GUI的方式让程序员操作,也是一条路。
2、 什么是意图?
意图是意图编程的核心,所以要一次性的给意图下一个定义,将会是一个非常费解而复杂的定义,所以我将从实例来引出意图的一些侧面,让你在多个方面有了一些印象之后,自然就明白了什么是意图编程中的意图了。 从这么一棵AST开始吧:
这是对应的代码:
int x;
x=3;
while(x<5) {
}
在传统的编译过程中,编译器的代码生成部分会对这颗语法树进行解释。解释的实际行为就是把这颗代码树转换为目标代码。在这种转换的过程中,体现出了这颗树的程序语义。在编译器内部可能就有这么一个switch语句switch(node) {
case “while”:…
case “if” ..
case …
} (仅仅表意)
编译器对于AST的节点可能有哪几种,每一种具体的节点类型的语义有着非常清楚的认识。而在意图编程中,就不是这样了。AST变成了这样的一种形式,AST就不再是AST了,应该叫IPT(Intentional Programming Tree)了。这里我们可以看到,我们写的语句成了意图的实例,而这实例又链接到了库中的意图。在代码生成的时候,IP系统会询问每个Intention,怎么来处理这颗用户写的树。Intention能够对这样的问题做答,并且知道IP系统对树进行转换(transform)。把树转换成只具有原语的形式。可以这么来理解原语,汇编中的指令,或者HTML中的标签。 这种转换是从树到树的转换,可以把Intention的转换类比于XSL,而源代码的树就是XML。但是在具体的转换过程中(IP把这种转换称为reduce),有很多的规则和限制,这是一个非常复杂的过程。能够找到的文献中,对于这种形式的代码生成,也是着墨不多,笔者也没有足够的计算机和数学方面的能力,能够给出一个完整的生成过程的理论来。 这样一来,代码生成的具体行为权利就从写死的编译器中下放到了库中,只是这种库是一种很特殊的库,意图库。意图不但要负责其实例的转换,也就是代码生成。而且要负责相关的调试支持,也就是从目标代码到源代码的对应,相当于代码生成的反向工程。还有就是意图实例的GUI显示和输入,以及代码控制(版本合并等)等操作。 总体的思想就是把以前编译器中的抽象提出来,并统一于Intention之下。从而把以前编译器的权利下放到库中。达到的效果是语言特征的无限扩充。相应的难点是编译器对于AST的内容一无所知,而具体的代码生成过程将不容易。在具体的实施过程中就会发现前面提到的转换过程并不是一件容易的事情。不但是指导生成不容易,就是知道GUI的呈现和编辑也不容易,试想操作系统的差异和IDE的差异,怎样的一种机制能够足够灵活呢?还有目标代码的机器模型的差异,等等。
意图编程对于管理复杂度实践的意义
意图编程能成为管理复杂度方面的先驱理念的理想载体。(no promise) 现今管理复杂度方面的各项技术似乎都有一个共识,那就是领域工程。而意图编程就是实现DSL的理想载体。而且更重要的,IP提供了一种从现状到极乐世界的渐进路线。从用现在技术表示的意图,到用高层抽象的DSL表示的意图之间的一种渐进转换的可能。DSL的例子可以是:我吃饭。这样的高层的抽象语言,可以通过IP表达出来,然后有具体的Intention库进行实现。IP在实现DSL方面的意义是降低了从头设计和实现推广一种专有语言的负担。我们不需要自己写新的解析器了,不用管语言的完备性了,甚至不用花大把的银子来推广了,我们可以很容易的交付给最终用户。