解釋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方面的意義是降低了從頭設計和實現推廣一種專有語言的負擔。我們不需要自己寫新的解析器了,不用管語言的完備性了,甚至不用花大把的銀子來推廣了,我們可以很容易的交付給最終用戶。
浙公網安備 33010602011771號