解释Intentional Programming

——三种视角的视图

作者:taowenmo2mo@163.com

摘要

本文的目的是用尽可能简明的语言记录下笔者对于Intentional Programming的初级认识,以把这激动人心的技术传播给更多人。但是限于理论发展的现状,资料的完备情况,以及最重要的,笔者的认知程度,并不能保证文中所记内容的准确性。

概览

Intentional Programming是对传统编程语言的一种颠覆,因而是对编译原理,程序语言设计理论的一种颠覆,是管理复杂度技术的一种远景技术,对程序员乃至普通个人的编程体验的一种全新模式。

这就是我能给出的无内容概要。循此概要而去,我将从这三个角度来记录一些理解:

1、  编译原理和程序语言设计理论

2、  管理复杂度的实践技术

3、  编程体验

意图编程的理论实质

意图编程对于传统的编译原理和程序语言的设计理论是一种颠覆。

 

从编译原理来说:

首先要声明的是,笔者是一个数学系的学生,并没有正统地学习过编译原理,所以对于具体地细节极可能似是而非,或者干脆是谬误。

传统的编译过程是这样的:


而意图编程是这样的


从图中可以看到,
GUI的交互代替了文法解析。而我用蓝色标注意图编程的“代码生成”的目的是把它与上面的代码生成区别开来,因为两者的实现手段是完全不同的。因为在解析和代码生成两个阶段的巨大差异,所以我说意图编程对于传统的编译理论是一种颠覆。

具体来看一个例子就能说明两种过程之间的区别了,先来看传统的语言:

int x;

x = 1;

 

从程序语言设计理论来说:

传统的编程语言大致可以分为:面向过程,面向对象,泛函式,逻辑式等。各自的代表有FortranSimulaLispProlog。但是这几种编程范型彼此之间为什么不同呢?我想大致因为它们彼此之间拥有不相交的语言特征

从语法的层面来看语言的特征,列举一二:

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).

Facttermrule等代表了其最明显的语言特征

从语法层次来看,这些语言特征的体现在AST(抽象语法树)的一些节点上。不同语言对于这些节点的语义解释构成了其独特的语言特征。


本质上说,语言的特性,就是给
AST的节点赋上的语义,而这种语义体现又完全体现在代码生成之中。

在意图编程中,这个过程是:


这里所说的意图库具体是什么在下面描述,这里所提供的语义是抽象意义上的,具体的实际表现就是意图库完全操控了从抽象语法树到目标代码的代码生成过程,在这个代码生成过程中体现了其语义,从而体现了一定的语言特征。

如此定义语义,定义语言特征,如此根据语言特征划分程序语言,可以得出一个意图编程包含面向过程∪面向对象∪泛函∪逻辑∪……的结论。

 

综述了两个方面的突破之后,留下了一大堆的问号:通过GUI来操作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的代码输入可以完全和文法无关。

无论易语言的IDEGUI如何,至少通过这么一个实际例子证明了,AST的生成不是华山一条路。通过对具有文法结构的源代码文本进行解析(parse)是一条路,直接用GUI的方式让程序员操作,也是一条路。

 

2、  什么是意图?

意图是意图编程的核心,所以要一次性的给意图下一个定义,将会是一个非常费解而复杂的定义,所以我将从实例来引出意图的一些侧面,让你在多个方面有了一些印象之后,自然就明白了什么是意图编程中的意图了。

从这么一棵AST开始吧:


这是对应的代码:

int x;

x=3;

while(x<5) {

}

在传统的编译过程中,编译器的代码生成部分会对这颗语法树进行解释。解释的实际行为就是把这颗代码树转换为目标代码。在这种转换的过程中,体现出了这颗树的程序语义。在编译器内部可能就有这么一个switch语句

switch(node) {

case “while”:…

case “if” ..

case …

} (仅仅表意)

编译器对于AST的节点可能有哪几种,每一种具体的节点类型的语义有着非常清楚的认识。而在意图编程中,就不是这样了。AST变成了这样的一种形式,AST就不再是AST了,应该叫IPTIntentional 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方面的意义是降低了从头设计和实现推广一种专有语言的负担。我们不需要自己写新的解析器了,不用管语言的完备性了,甚至不用花大把的银子来推广了,我们可以很容易的交付给最终用户。

 

渐进演化,其实原理很简单。因为现有语言都是有AST的,我们只需要针对具体的语言提供不同的Intention,比如给C建一套意图。然后AST就能转换为IPT了。这样用C写的遗产代码就进入了IP的体系了。然后我们可以通过添加新的高层意图,部分重写改进精化原来的代码结构,逐渐把以前埋藏在实现细节中的意图用直接的Intention凸现出来。这一点是非常诱人的。

意图编程在编程体验方面的意义

意图编程带来全新的编程体验从而达到人人都能写程序的理想世界。(no promise)

 

因为是通过GUI来输入和输出代码的,这样代码的就能有非常丰富的直观表现,能够让代码具有更好的亲和力。比如说,能够用中文来显示代码。比如说,能够直接显示出代码的流程。

 

又由于语言是无限扩充的,实现领域专有的语言和语义是可行的。这样就有可能给矩阵计算实现一套DSL,并用GUI的丰富表现来表达。这样一来,数学家就能在不了解下层实现的基础上,通过和纸上运算类似的表现和记法进行算法意图表达,直接表达为矩阵运算的DSL。然后再有具体的意图库做出具体的实现。

 

试想如果有了各行各业的意图库,那么就能让行业的专家来描述业务逻辑,让计算机从业人员把行业的意图表达为计算机的实现。而时下的编程体验,阻碍了行业专家的直接意图表达。而且,我们要看到,仅仅有GUI表现,面向AST编程是达不到上面所说的理想景象的。易语言的目标大抵类似,但是它仅仅实现了意图的编程的前端部分,缺少了后端的最核心的意图库这样的东西,易语言对于行业专家来说,仍然是天书,仍然是一门难语言。

posted on 2004-10-02 03:35  taowen  阅读(1374)  评论(0编辑  收藏  举报