Language Oriented Programming : The Next Programming Paradigm
Sergey Dmitriev, JetBrains
本文blog來源:http://www.uuzone.com/blog/oiunt/891/
現(xiàn)在是軟件開發(fā)中開始下一次技術(shù)革命的時(shí)候了,而這次革命的輪廓正變得越來越清晰。下一代編程范型也在接近我們,但仍然沒有完全成形--不同的部分有不同的名稱:Intentional programming, MDA, generative programming, 等等;我建議把把所有這些新方法歸并為一個(gè)名字: ‘language-oriented programming’(面向語言的編程), 而本文將闡述這種新的編程范型的主要原則
今天主流的編程方法有一些內(nèi)在的假定像脖子上的繩索一樣桎梏著我們,盡管大部分程序員還沒有意識(shí)到它;即使算上在編程領(lǐng)域取得的所有進(jìn)步,我們也仍然處于石器時(shí)代;我們有我們信賴的石斧(面向?qū)ο缶幊蹋軌驖M足我們的需要,但是當(dāng)用它來對(duì)付最困難的問題時(shí),它會(huì)裂成碎屑;為了超越石器前進(jìn),我們必須馴服烈火,只有這樣,我們才能鑄造出新的工具,激發(fā)一個(gè)創(chuàng)作的新時(shí)代,和新技術(shù)的爆發(fā)
我將討論編程的局限,它強(qiáng)迫程序員像計(jì)算機(jī)一樣思考,而不是令計(jì)算機(jī)像程序員一樣思考;這是嚴(yán)重的,根深蒂固的局限,需要花費(fèi)巨大的努力去克服它;當(dāng)我說這將是編程中下一個(gè)大的范型轉(zhuǎn)換時(shí)我并沒有自命不凡;我們需要徹底重新定義我們編寫程序的方法
本文中,我表述了我的觀點(diǎn)和我當(dāng)前在Language Oriented Programming (LOP)上的工作;首先我將展示目前主流編程方法的錯(cuò)誤,然后我會(huì)使用示例來解釋LOP的概念,它們基于我已有的一個(gè)LOP的實(shí)現(xiàn):the Meta Programming System (MPS). 本文有意只是給你一個(gè)對(duì)LOP的驚鴻一瞥,目的是激發(fā)你對(duì)這個(gè)思想的興趣,并希望能夠得到反饋和討論
Part I.
LANGUAGE ORIENTED PROGRAMMING OVERVIEW
Language Oriented Programming and the Meta Programming System
理想的,做一個(gè)程序員意味著我可以對(duì)計(jì)算機(jī)做任何事情,我有完全的自由,完全的控制;但實(shí)際上,今天的程序員只有非常受限的自由;當(dāng)然,我確實(shí)可以在計(jì)算機(jī)上做任何事情,但其中一些事情花費(fèi)了我許多年的努力,而它們實(shí)際上只需要少的多的時(shí)間;一定有什么事情不對(duì)勁
程序員被限制是因?yàn)樗麄兩钌钜蕾囉谀切┧麄儾荒茌p易改變的編程基礎(chǔ)設(shè)施:編程語言和開發(fā)環(huán)境;如果我需要一些語言的擴(kuò)展,我只能等待語言的設(shè)計(jì)者去更新它;如果我需要我的IDE有一些額外的強(qiáng)大功能,我只能等待供應(yīng)商來添加新特性;就是這些依賴限制了我完全的自由;當(dāng)然,我可以寫我自己的編譯器和IDE,實(shí)際上,這也是我啟動(dòng)了IntelliJ IDEA的原因,因?yàn)槲覅捑肓艘蕾嚞F(xiàn)有的弱弱的Java IDE;但是,這會(huì)花費(fèi)大量的時(shí)間和努力,并且顯而易見,對(duì)大部分程序員來說是不可行的;理論上的自由和實(shí)際的自由之間存在巨大的差異;下文中當(dāng)我談到自由時(shí),我指的是實(shí)際的自由
獲得自由的途徑是減少我們的依賴層次;例如,Java的一個(gè)主要目標(biāo)是減少對(duì)操作系統(tǒng)的依賴,給開發(fā)者在不同操作系統(tǒng)上部署的自由;因此,為了在語言和環(huán)境之上獲得自由,我們需要減少對(duì)它們的依賴
為什么這是一個(gè)問題呢?任何general-purpose的語言,像Java和C++,給了我們用計(jì)算機(jī)做任何事情的能力;這是事實(shí),至少理論上是這樣,但是,general-purpose的語言趨向于如同后面我將講到的般生產(chǎn)效率低下;作為一種替代,我們可以使用domain-specific languages(DSLs,aka ‘little languages’),它們被精心設(shè)計(jì)成在特定問題域具有高度生產(chǎn)率,比如用SQL編寫數(shù)據(jù)庫查詢;DSLs的強(qiáng)大之處,領(lǐng)域相關(guān),也正是它們的弱處,因?yàn)槿魏握鎸?shí)世界中的程序都會(huì)包括許多不同的領(lǐng)域
general-purpose 和 domainspecific 之間,并不是對(duì)立的;我需要所有的自由,我希望能夠做任何事情,同時(shí)有很高的生產(chǎn)效率;目前為止還沒有什么好方法能夠做到這點(diǎn);理想情況下,我能夠?yàn)槌绦虻母鱾€(gè)特定部分使用不同的語言,而它們能夠融洽的一起工作,并且開發(fā)環(huán)境會(huì)完全支持這些語言,包括重構(gòu),代碼補(bǔ)全,導(dǎo)航,以及主流語言具有的所有其它生產(chǎn)力工具
為了獲得這種獨(dú)立性,我需要有創(chuàng)建、重用、修改語言和環(huán)境的自由;為了使這種自由是可行的,它需要很容易的被獲得;如果我們解決了易于進(jìn)行語言和環(huán)境的開發(fā)的問題,對(duì)程序員來說將是一個(gè)巨大的進(jìn)步;這就是Language Oriented Programming的切入點(diǎn)
要理解Language Oriented Programming是什么,讓我們首先看一下今天的主流編程方法,它基本上是這樣:
思考: 你需要編程解決一個(gè)問題,因此你在你的頭腦里形成了如何解決這個(gè)問題的概念模型
選擇: 你選擇了某種general-purpose的語言來編寫解決方案
編程: 你通過將你的概念模型艱難的映射到編程語言來編寫解決方案
編程這一步是瓶頸所在,因?yàn)榇蟛糠智闆r映射不是容易的和自然的;這種方法在程序員表達(dá)復(fù)雜的設(shè)計(jì)方面已經(jīng)被證明是低效的;相對(duì)的,下面是LOP的工作方式:
思考: 你需要編程解決一個(gè)問題,因此你在你的頭腦里形成了如何解決這個(gè)問題的概念模型
選擇: 你選擇了某些特定的DSLs來編寫解決方案
創(chuàng)建: 如果沒有合適的DSL適合你的問題,你便創(chuàng)建一種DSL來適應(yīng)你的問題
編程: 你通過將你的概念模型相對(duì)直接的映射到DSLs來編寫解決方案
現(xiàn)在,編程這一步is much less of a 瓶頸了,因?yàn)镈SLs大大簡(jiǎn)化了如何將問題翻譯成某種計(jì)算機(jī)能夠理解的東西;看起來困難已經(jīng)簡(jiǎn)單的轉(zhuǎn)移到了“創(chuàng)建”這一步,然而,通過聯(lián)合使用工具支持和將LOP應(yīng)用到自身,將使這一步更加簡(jiǎn)單
LOP 背后的動(dòng)機(jī)基本是這樣的:我想用我正試圖解決的問題相關(guān)的概念和意圖的詞匯來工作,而不是被迫將我的思想翻譯成某種general-purpose的語言所能理解的概念(比如:類,方法,循環(huán),條件,等等...);為了達(dá)到這個(gè)目標(biāo),我需要使用domain-specific languages;怎樣得到它們呢?創(chuàng)建它們;
我已經(jīng)開始開發(fā)一個(gè)通用的平臺(tái)(the Meta Programming System)來設(shè)計(jì)domainspecific languages,帶有工具支持和開發(fā)環(huán)境;它將允許程序員像現(xiàn)在編寫程序一樣容易的來定義語言;這個(gè)平臺(tái)將完全支持LOP,給程序員為程序的每一部分選擇使用最合適的語言的自由,而不是將他們綁在某種固定的general-purpose的編程語言上
MPS 只是Language Oriented Programming的一個(gè)示例,盡管我在這里使用MPS來做示例,而實(shí)際上LOP可以用許多不同的方法來實(shí)現(xiàn),你自己就可能知道一些替代方法;LOP 的概念不等同于它的實(shí)現(xiàn),就像OOP的概念不等同于Java或C++或Smalltalk一樣
What Is Wrong with Mainstream Programming
你知道這則古老的諺語:"If it ain't broke, don't fix it". 主流編程方法很明顯不完整,我見過它帶來的很多問題,而大部分滋生于這樣一個(gè)事實(shí):general-purpose的語言沒有一種方法來完全支持任意的領(lǐng)域,同樣也沒有一種統(tǒng)一的domain-specific language;下面是將被LOP解決的主流編程中三個(gè)最糟糕的問題:
Time Delay to Implement Ideas
對(duì)我來說,最嚴(yán)重的問題是,在我確切的知道如何解決一個(gè)問題,和我通過一個(gè)程序成功的向計(jì)算機(jī)傳達(dá)解決方案之間,有一個(gè)很長(zhǎng)的時(shí)間差;我可以用幾個(gè)小時(shí)的時(shí)間向另外的程序員解釋問題和解決方案,而將解決方案編碼到計(jì)算機(jī)中將花費(fèi)長(zhǎng)的多的時(shí)間;這是因?yàn)閷?duì)另外的程序員,我可以使用表達(dá)能力非常豐富的自然語言,而對(duì)計(jì)算機(jī),我只能使用某種表達(dá)能力差很多的general-purpose的編程語言;今天的編程語言只能表達(dá)幾十種概念,而自然語言能夠簡(jiǎn)潔的表達(dá)千萬種概念;因此,向另外的程序員解釋問題,我可以表達(dá)很高層的思想,而對(duì)計(jì)算機(jī),我必須表達(dá)每一步的每一個(gè)細(xì)節(jié)
在主流編程中,大部分花在“編程”上的時(shí)間,實(shí)際上是在尋找用編程層次的抽象的術(shù)語來表達(dá)自然語言的概念的方法,而這是很困難的,沒多少創(chuàng)造性的,或多或少是一種時(shí)間的浪費(fèi)
舉個(gè)例子,今天大量的開發(fā)時(shí)間花費(fèi)在面向?qū)ο蟮脑O(shè)計(jì)(OOD)上,在程序員表達(dá)類、繼承、關(guān)聯(lián)等方面這確實(shí)是一種還算有創(chuàng)造性的過程;這項(xiàng)實(shí)踐的目的是用面向?qū)ο蟮男g(shù)語,如類和方法,來表達(dá)程序;OOD的過程是必要的,因?yàn)橹T如類和方法等是面向?qū)ο笳Z言能夠理解的僅有的抽象,它看起來是必要和有創(chuàng)造性的,但是使用Language Oriented Programming,OOD根本就不需要
Understanding and Maintaining Existing Code
下一個(gè)問題是理解和維護(hù)現(xiàn)存代碼;不管它是另一個(gè)程序員寫的還是我寫的,問題都一樣;因?yàn)間eneral-purpose的語言需要我把高層的領(lǐng)域概念翻譯為低層的編程語言特性,在最終的程序中,很多高度概括的視角、藍(lán)圖都丟失了;當(dāng)我在以后重新翻閱程序時(shí),我不得不通過逆向工程來了解我最初的意圖是什么,我頭腦中的模型是什么;至少,我必須在腦海中重新建造最初在翻譯到general-purpose的編程語言的過程中丟失的信息
解決這個(gè)問題的傳統(tǒng)方法是寫注釋或其它形式的文檔來記錄設(shè)計(jì)信息和模型信息,已經(jīng)有幾個(gè)方面的因素證明了這是一種脆弱的解決方案,至少包括編寫這些輔助文檔的成本、以及文檔和代碼逐漸不同步的趨勢(shì);并且,還有一個(gè)沒被廣泛認(rèn)識(shí)到的事實(shí),就是文檔并不能直接連接到它所記錄的概念;注釋和源代碼被綁定到同一個(gè)地方,但是概念可能在源代碼的多個(gè)地方被表達(dá);其它類型的文檔徹底從源代碼中分離出來,只能間接的引用源代碼;理想情況下,代碼應(yīng)該是自我描述的,我應(yīng)該只閱讀代碼本身來理解代碼,而不是什么注釋和外部的文檔
Domain Learning Curve
第三個(gè)主要的問題是對(duì)語言進(jìn)行領(lǐng)域相關(guān)的擴(kuò)展;例如,在OOP中擴(kuò)展語言的主要方法是使用類庫;問題是類庫不是用領(lǐng)域概念相關(guān)的術(shù)語來表達(dá)的,而是用低層的 general-purpose的抽象諸如類和方法等來表達(dá);因此,庫很少能夠直接表述領(lǐng)域概念,它們必須引入額外的枝節(jié)(如一個(gè)類的運(yùn)行時(shí)行為)來完成到領(lǐng)域概念的映射;兩個(gè)很好的常見例子是GUI庫和Database庫
學(xué)習(xí)這些類庫不是一項(xiàng)簡(jiǎn)單的任務(wù),即使你是個(gè)領(lǐng)域?qū)<遥灰驗(yàn)閺念I(lǐng)域到語言的映射不是直接的,你必須學(xué)習(xí)這種映射;這意味著一個(gè)陡峭的學(xué)習(xí)曲線;通常我們?cè)噲D用大量的指南和文檔來解決這個(gè)問題,但是學(xué)習(xí)這些將花費(fèi)大量時(shí)間;當(dāng)一個(gè)類庫變得復(fù)雜的時(shí)候,它也變得更難以學(xué)習(xí),程序員將因此失去學(xué)習(xí)它的動(dòng)機(jī)
甚至當(dāng)掌握了這種復(fù)雜的映射之后,依然還會(huì)很容易的誤用類庫,因?yàn)殚_發(fā)環(huán)境(像編譯器和編輯器)不能幫助你正確的使用類庫,對(duì)這些工具來說,調(diào)用一個(gè)GUI 對(duì)象的方法和調(diào)用一個(gè)DB對(duì)象的方法是一樣的:它們都只是對(duì)象上的方法調(diào)用,沒有任何更多的意思;記住哪些類和方法應(yīng)該被調(diào)用,以什么順序被調(diào)用,等等,都是使用者的責(zé)任
甚至即使你既是領(lǐng)域?qū)<矣质穷悗斓氖褂脤<遥踩匀挥惺褂妙悗炀帉懙某绦蚴秩唛L(zhǎng)的問題;相對(duì)簡(jiǎn)單的領(lǐng)域概念需要復(fù)雜的措施來正確的調(diào)用;例如,任何用過Swing的開發(fā)者都清楚這一點(diǎn);編寫簡(jiǎn)單的程序就已經(jīng)花費(fèi)太長(zhǎng)的時(shí)間了,復(fù)雜的程序甚至更糟
Details of LOP
What Is a Program in LOP?
今天,百分之九十九的程序員認(rèn)為編程就是編寫一串計(jì)算機(jī)能夠執(zhí)行的指令集;我們被教育說計(jì)算機(jī)建立在圖靈機(jī)模型之上,因此它們用指令集的術(shù)語來“思考”;但是這種編程的觀點(diǎn)是有缺陷的,它混淆了編程的目的和手段;我將為你演示LOP為什么優(yōu)于傳統(tǒng)編程方法,但首先我必須澄清以下事實(shí):一個(gè)LOP的程序,不是一串指令集;那么它是什么呢?
當(dāng)我有一個(gè)問題要解決,我在頭腦中思考解決方案,這個(gè)解決方案用單詞、標(biāo)記、概念、思想,或者任何你喜歡的稱呼來表述,它是我頭腦中如何解決問題的模型;我?guī)缀鯊奈窗阉鼈兿胂蟪梢欢阎噶罴俏艺诠ぷ鞯念I(lǐng)域中特定的具有內(nèi)在聯(lián)系的概念的集合;例如,當(dāng)我思考GUI領(lǐng)域時(shí),我想象“這個(gè)按鈕到那邊去,這個(gè)輸入域到這邊來,這個(gè)組合框里面需要有一些數(shù)據(jù)的列表”;我甚至只是在頭腦中把它畫出來,根本不用任何言語
我之所以認(rèn)為這種意念模型是一種解決方案是因?yàn)槲夷軌蛴米銐虻募?xì)節(jié)向另一個(gè)程序員解釋這個(gè)模型,使他能夠坐下來編寫一個(gè)解決這個(gè)問題的程序(比如用 Java);我不需要非得用編程語言的術(shù)語來解釋這個(gè)方案,它可以是任意形式;比如,為了解釋如何布局一個(gè)GUI的窗體,我只需要畫出這個(gè)窗體;如果繪畫有足夠的細(xì)節(jié),繪畫本身就代表了解決方案;這種領(lǐng)域相關(guān)的表述應(yīng)該就是程序。換句話說,應(yīng)該有一種方法允許我們使用這種表述作為真正的程序,而不僅僅是與其它程序員交流的手段;于是這便導(dǎo)出了我對(duì)程序非正式的定義:一個(gè)程序是任何對(duì)一個(gè)問題無歧義的解決方案,或者,更精確一點(diǎn):一個(gè)程序是對(duì)某個(gè)領(lǐng)域的某個(gè)問題的解決方案的任何使用領(lǐng)域相關(guān)概念表達(dá)的,精確定義的模型
這就是我認(rèn)為程序員應(yīng)該擁有創(chuàng)建他們自己的語言的自由的主要原因:這樣他們就能夠用更加自然的形式來表達(dá)解決方案;General-purpose的語言是無歧義的,但是太冗余和易于出錯(cuò);自然語言(如英語)表達(dá)能力十分豐富,但目前它難以使用因?yàn)樗痪_太不形式化了;我們需要能夠容易的創(chuàng)建形式化的,精確定義的,領(lǐng)域相關(guān)的語言;因此Language Oriented Programming將不只是編寫程序,還包括創(chuàng)建用來編寫程序的語言;我們的程序?qū)⒈痪帉懙母咏鼏栴}域而不是計(jì)算機(jī)指令集領(lǐng)域,因此它們將非常容易的被編寫
Programs and Text
人們習(xí)慣性的認(rèn)為程序是作為文本來存儲(chǔ)的,也就是說,一個(gè)字節(jié)流;為什么不應(yīng)該是呢?畢竟有無數(shù)的工具來編輯、顯示、操作文本;今天的編程語言的核心部分是文法器,解析器,編譯器和面向行的調(diào)試器;但是程序的文本只是程序的一種表現(xiàn)形式;程序不是文本;強(qiáng)行把程序塞到文本里引起了大量你可能還不知道的問題;我們需要一種不同的方法來存儲(chǔ)并和我們程序一起工作
當(dāng)編譯器編譯源代碼時(shí),它把文本解析成稱作抽象語法樹的樹狀結(jié)構(gòu);當(dāng)程序員閱讀源代碼時(shí),他們?cè)谀X海中做了本質(zhì)上相同的事情;我們?nèi)匀徊坏貌豢紤]程序的樹狀結(jié)構(gòu);這就是為什么我們要有花括號(hào),方括號(hào),圓括號(hào)等;這也是為什么我們需要格式化和縮進(jìn)代碼和遵守編碼規(guī)范,因?yàn)檫@樣就能夠更容易的閱讀源代碼
我們?yōu)槭裁词褂梦谋敬鎯?chǔ)呢?因?yàn)楫?dāng)前,閱讀和編輯程序最方便和最通用的方法還是使用文本編輯器;但是我們會(huì)為此付出代價(jià),因?yàn)槌绦虻奈谋颈硎居兄卮蟮娜秉c(diǎn),其中最重要的是基于文本的編程語言非常難于擴(kuò)展;如果程序以文本的形式存儲(chǔ),你就會(huì)需要一個(gè)無歧義的文法器來解析程序;當(dāng)為語言加入新特性時(shí),維護(hù)語言無二義性的擴(kuò)展變得日益困難;我們將需要發(fā)明更多類型的括號(hào)、操作符、關(guān)鍵字、順序規(guī)則、嵌套,等等;語言的設(shè)計(jì)者們花費(fèi)了無數(shù)時(shí)間來思考語法,并試圖發(fā)現(xiàn)擴(kuò)展語言的新方法
如果我們打算讓創(chuàng)建語言變得容易,我們就需要將程序的表示和存儲(chǔ)從程序本身分離開;我們應(yīng)該直接將程序存為結(jié)構(gòu)圖,因?yàn)檫@允許我們對(duì)語言做任何我們喜歡的擴(kuò)展;有時(shí),我們甚至根本不需要考慮文本存儲(chǔ);今天的一個(gè)很好的例子是Excel spreadsheet.百分之九十九的人根本不需要處理存儲(chǔ)格式,當(dāng)這成為問題時(shí)總會(huì)有各種導(dǎo)入導(dǎo)出功能可用;今天我們使用文本的真正原因是我們沒有比文本編輯器更好的編輯器,但是我們可以改變這一點(diǎn)
問題是文本編輯器很愚蠢,并且不知道如何與程序的圖狀結(jié)構(gòu)一起工作;但是使用正確的工具,編輯器將能夠直接和圖狀結(jié)構(gòu)一起工作,并且能夠讓我們自由的使用任何編輯器提供的我們喜歡的可視化表現(xiàn)形式;我們可以把程序做成文本、表、圖、樹、或其它任何形式;我們甚至能為不同目的使用不同的表現(xiàn)形式,比方說,圖形化表示用來瀏覽,文本化表示用來編輯;我們能夠?yàn)榇a的不同部分使用領(lǐng)域相關(guān)的表示,比如為數(shù)學(xué)公式使用圖形化的數(shù)學(xué)符號(hào),為圖表使用圖形化的圖表,為 spreadsheets使用行和列,等等;我們能夠?yàn)閱栴}域使用最合適的表現(xiàn)形式,可以是文本,但不限于文本;最好的表現(xiàn)形式依賴于我們?nèi)绾嗡伎紗栴}域;表現(xiàn)形式的靈活性也將使我們的編輯器比以往更加強(qiáng)大,因?yàn)椴煌谋憩F(xiàn)形式有不同的方式去編輯它們
What Is a Language in LOP?
最后,我應(yīng)該闡明我認(rèn)為的“語言”是什么;在LOP中,一種語言是通過三個(gè)主要的要素來定義的:結(jié)構(gòu)、編輯器、和語義;結(jié)構(gòu)定義了抽象語法、支持的概念、以及如何安排它們;編輯器定義了具體的語法,如何描繪和編輯語言;語義定義了行為,它如何被解釋,和/或它如何被轉(zhuǎn)換成可執(zhí)行代碼;當(dāng)然,語言還可以有其它方面,比如約束和類型系統(tǒng)
Part II.
INTRODUCTION TO META PROGRAMMING SYSTEM
Creating Languages in MPS
我已經(jīng)解釋了為什么我們需要容易的創(chuàng)建新的語言,但是,我們?nèi)绾尾拍茏屗菀啄兀咳绻鉻urn around這個(gè)問題,并且把Language Oriented Programming應(yīng)用于它自身,你會(huì)很快看到答案;This calls for a little self-referential bootstrapping, which can seem tricky, but be patient. 一旦你理解了這個(gè),你將得到LOP真正的力量(一個(gè)LOP的元層次)
回顧一下LOP的理念:使創(chuàng)建DSLs更容易,而這些DSLs將使編寫程序更容易;但就像我已經(jīng)說明的,LOP中的‘程序’不局限的意味著你用過的典型的 “一堆指令集”的程序;對(duì)某個(gè)領(lǐng)域中某個(gè)問題任何無二義性的解決方案都是‘程序’;因此如果你設(shè)想一下“創(chuàng)建新語言”這個(gè)領(lǐng)域,那么這個(gè)領(lǐng)域中的‘程序 ’,本身就是一種新語言的定義,可以作為一個(gè)解決方案來思考,就像任何其它領(lǐng)域的解決方案一樣;
因此,應(yīng)用LOP的思想,使“創(chuàng)建新語言”更容易的方法,就是創(chuàng)建一種特定的專注于“創(chuàng)建新語言”這個(gè)領(lǐng)域的DSL;通過應(yīng)用這些language- building DSL,我們可以使制造新語言更容易;讓我們看幾種language-building語言的例子,使你更好的理解它們是如何工作的;這里只是一個(gè)概述,以后的文章我會(huì)更詳細(xì)的描述它們
Structure Language
最小最少,我們需要定義新語言的‘結(jié)構(gòu)’;這是我們何以能夠編寫“精確定義”的程序的原因;語言的結(jié)構(gòu)并不意味著它的文本形式的文法--像我提到過的,這種語言甚至根本就沒有文本表示而只有圖形化表示
在實(shí)踐LOP的時(shí)候,大部分情況下,你會(huì)工作在兩個(gè)層次的編程中:元層次和程序?qū)哟危荒阍谠獙哟沃卸x語言,在程序?qū)哟沃芯帉懗绦颍划?dāng)定義一種新語言的結(jié)構(gòu)時(shí),你會(huì)使用一種language-structure DSL來定義你的新語言,而這時(shí),你將同時(shí)工作在這種language-structure DSL的程序?qū)哟魏托抡Z言的元層次中
在MPS 中,程序?qū)哟蔚拿總€(gè)節(jié)點(diǎn)都有一種“類型”,簡(jiǎn)單的連接到元層次的另一個(gè)節(jié)點(diǎn);程序?qū)哟蔚倪@個(gè)節(jié)點(diǎn)被稱作這種類型的一個(gè)“實(shí)例”;元層次中的“類型”節(jié)點(diǎn)則定義了這種類型的實(shí)例能夠擁有的關(guān)系和屬性;描述這種元層次語言結(jié)構(gòu)的語言,就被簡(jiǎn)單的稱為“Structure Language”
用Structure Language定義一種語言的抽象語法,你應(yīng)該只是枚舉這種語言所有的類型;類型簡(jiǎn)單的表示了這種語言支持的特性或者概念;每個(gè)概念應(yīng)該用它的名字、實(shí)例的內(nèi)部屬性、實(shí)例與其它節(jié)點(diǎn)之間的關(guān)系(通常是連接)來定義
存在兩種可能的關(guān)聯(lián);第一種是類似聚合的關(guān)聯(lián),它形成了概念模型的父子樹結(jié)構(gòu);第二種是非聚合的,自由形式的關(guān)聯(lián),它可以連接到系統(tǒng)中任何其它的節(jié)點(diǎn);關(guān)聯(lián)有兩個(gè)端點(diǎn):源和目標(biāo);關(guān)聯(lián)有角色,你可以定義每個(gè)角色的名稱、每個(gè)端點(diǎn)的多重性,每個(gè)目標(biāo)節(jié)點(diǎn)的類型;多重性可以是1, 0..1, 0..n, 1..n等,讓你能夠約束關(guān)聯(lián)可以創(chuàng)建多少連接;關(guān)聯(lián)的目標(biāo)類型可以被用來約束哪些類型的節(jié)點(diǎn)可以被連接在一起
因此,使用新語言編寫程序包括:創(chuàng)建語言中概念的實(shí)例、為實(shí)例的屬性賦值、根據(jù)語言概念定義的關(guān)系將程序中的節(jié)點(diǎn)連接在一起;所有這些將會(huì)被強(qiáng)大的編輯器支持,你能夠?yàn)槟愕恼Z言定義這種編輯器
Editor Language
那么,編寫和操作概念模型的界面應(yīng)該是什么呢?我們的語言需要幾種類型的編輯器,但是我們不想要一個(gè)通用的編輯器;經(jīng)驗(yàn)表明通用的編輯器不能像我們希望的那樣有用;我們希望快速的編寫模型,因此我們需要專為我們的語言概念定做的特殊的編輯器;一定程度上,編輯器是語言的一部分,而我們的目標(biāo)是容易的創(chuàng)建新語言,那么創(chuàng)建新的編輯器也應(yīng)該很容易;本質(zhì)上,我們需要一種創(chuàng)建編輯器的語言,在MPS中,它被稱為Editor Language
當(dāng)人們聽我說我們的程序?qū)⒋鎯?chǔ)為圖形并且我們需要特定的編輯器,我確信很多人認(rèn)為我將要談到圖形編輯器,事實(shí)不是這樣子的;盡管程序是圖形形式,編輯器卻不一定非得將程序描繪成圖形;事實(shí)上,只有少數(shù)情況下圖形編輯器才是有用的(也就是說,當(dāng)它合適的時(shí)候,比如對(duì)數(shù)據(jù)庫表);相反,我們的Editor Language有更好的靈感來源,諷刺的是,它來自文本編輯器
如果你用文本編輯器瀏覽一個(gè)典型的程序,你可以想象編輯器被分成了矩形單元;一些單元包含必需的標(biāo)識(shí)如關(guān)鍵字、花括號(hào)、圓括號(hào)等,其它的單元包含用戶定義的標(biāo)識(shí),如類和方法的名稱;大的單元由小的單元組成,像方法塊包含語句,而語句可能包含自己的嵌套塊;事實(shí)上,任何主流編程語言中任何良好構(gòu)造的程序都可以分解為矩形單元的集合;那么,在Editor Language中,你不需要想象這些單元,因?yàn)榫庉嬈骶褪呛?jiǎn)單的由矩形單元組成的
單元的使用有一些有趣的優(yōu)點(diǎn);首先,當(dāng)直接工作在程序圖形而不是程序文本上時(shí),單元可以完美的模仿甚至超過標(biāo)準(zhǔn)的文本編輯器;第二,單元不局限于文本,你可以往單元里塞進(jìn)顏色選擇器、數(shù)學(xué)符號(hào)、圖表、矢量圖、或任何別的什么;最后,這種單元形式的layout是可選的,程序員可以提供不同的機(jī)制,單元形式的 layout只是一種有用的缺省設(shè)置
因此,Editor Language幫助你定義語言中每個(gè)概念對(duì)應(yīng)的單元的layout;你可以定義哪些部分是不變的,像括號(hào)或其它修飾符號(hào),哪些是可變的,需要用戶去定義的;Editor Language也幫助你在你自己的編輯器中加入強(qiáng)大的特性,像自動(dòng)完成、重構(gòu)、導(dǎo)航、語法加亮、錯(cuò)誤加亮、以及任何其它你想到的事情;因此你能夠增加現(xiàn)在的編輯器如IntelliJ IDEA等擁有的功能到你自己的語言中;這是可能的,因?yàn)槌绦蚝驼Z言被構(gòu)造為圖形,而我們有專門的Editor Language幫助我們創(chuàng)造強(qiáng)大的編輯器
Transformation Language
Structure Language和Editor Language已經(jīng)共同提供了一些功能,你能夠用它們和其他人交流思想,比如畫UML圖,或者編寫其它類型的文檔;然而,大部分時(shí)間我們是想讓我們的代碼做點(diǎn)什么,因此,我們必須找到一種方法讓它能夠執(zhí)行;有兩種主要的方式來做這件事情:解釋和編譯
DSLs支持的解釋方式幫助定義計(jì)算機(jī)應(yīng)該如何解釋程序,DSLs支持的編譯方式幫助定義如何為程序產(chǎn)生可執(zhí)行代碼;我將在以后的文章中討論對(duì)解釋方式的支持,現(xiàn)在我想說明一下MPS是如何支持編譯方式的
編譯意味著拿到源代碼,并從中產(chǎn)生某種形式的可執(zhí)行代碼;對(duì)于結(jié)果代碼有多種可能的形式;為產(chǎn)生可執(zhí)行代碼,你可以生成本地機(jī)器碼,也可以生成虛擬機(jī)字節(jié)碼;或者,你可以生成另外一種語言的源代碼(比如Java,C++),然后用現(xiàn)有的編譯器轉(zhuǎn)換為可執(zhí)行代碼;類似的,你甚至可以產(chǎn)生某種解釋型語言的源代碼,用現(xiàn)有的解釋器解釋執(zhí)行
為了避免處理這么廣泛的目標(biāo)格式,我們的方法是用MPS來做每一件事;首先,你在MPS中使用Structure Language定義一種目標(biāo)語言,這種目標(biāo)語言和目標(biāo)格式之間應(yīng)該有直接的一對(duì)一的映射;例如,如果你的目標(biāo)格式是機(jī)器碼,你應(yīng)該用MPS定義一種對(duì)應(yīng)機(jī)器碼的目標(biāo)語言;如果目標(biāo)格式是Java源代碼,你應(yīng)該定義一種類Java的目標(biāo)語言;目標(biāo)語言不必支持目標(biāo)格式所有的功能特性,只為你需要的語言特性進(jìn)行簡(jiǎn)單的一對(duì)一的映射即可
那么現(xiàn)在,編譯分為兩個(gè)階段:一個(gè)簡(jiǎn)單的從目標(biāo)語言到最終結(jié)果的翻譯,一個(gè)更復(fù)雜的從最初的原始語言到中間目標(biāo)語言的轉(zhuǎn)換;翻譯階段是微不足道的,因此我們把精力集中于更有意思的轉(zhuǎn)換階段;至少,現(xiàn)在的問題簡(jiǎn)化為了如何將模型從一種語言轉(zhuǎn)換到另一種語言;但是,有可能源語言與目標(biāo)語言是完全不同的,導(dǎo)致轉(zhuǎn)換非常復(fù)雜,比如映射一個(gè)源節(jié)點(diǎn)到許多散布在目標(biāo)模型中的目標(biāo)節(jié)點(diǎn);我們想讓定義轉(zhuǎn)換盡可能的簡(jiǎn)單容易,因此我們需要一種模型轉(zhuǎn)換DSL來幫助我們;在MPS中,這種 DSL被稱為Transformation Language
代碼生成有三種主要的方法,我們將結(jié)合使用它們來定義模型轉(zhuǎn)換;第一種是遍歷方式,你枚舉源模型中所有節(jié)點(diǎn),檢視每一個(gè),并基于檢視到的信息生成目標(biāo)模型中的一些目標(biāo)節(jié)點(diǎn);第二種方式是使用模板和宏來定義如何生成目標(biāo)語言;第三種方式是使用模式匹配來查找在源模型中的哪些節(jié)點(diǎn)上應(yīng)用轉(zhuǎn)換
我們通過定義DSLs把這些方式結(jié)合起來以支持任何一種方法;這些DSLs將一起工作來幫助你定義從一種語言到另一種語言的轉(zhuǎn)換;例如,遍歷方式激發(fā)了 Model Query Language的靈感,它使枚舉節(jié)點(diǎn)和從概念模型中收集信息變得簡(jiǎn)單容易;你可以把它想象成某種針對(duì)概念模型的SQL;做為一種額外的獎(jiǎng)賞,擁有一種強(qiáng)大的查詢語言不只是對(duì)代碼生成有用(例如,能夠使編輯器更聰明)
Templates
模板方法工作方式類似Velocity或者XSLT;模板看起來很像目標(biāo)語言,但是允許你在模板的任何部分中添加宏;宏本質(zhì)上是當(dāng)運(yùn)行轉(zhuǎn)換的時(shí)候被執(zhí)行的代碼段;宏允許你檢視源模型(使用Model Query Language),并使用得到的信息對(duì)模板進(jìn)行“填空”,得到最終的目標(biāo)代碼
在圖5中,你可以看到為概念“Property”生成Java代碼的模板的定義,模板為屬性添加了field declarations, getters, setters等;這個(gè)模板是將代碼從Structure Language轉(zhuǎn)換為Java的生成器的一部分
既然模板看起來像目標(biāo)語言,你可以想象模板是用某種基于目標(biāo)語言的特殊的語言編寫的;這也是它事實(shí)上的工作方式;我們實(shí)際上使用一個(gè)生成器來為你生成模板語言,而不是手工為每一種可能的目標(biāo)語言創(chuàng)建模板語言;它基本上是復(fù)制目標(biāo)語言,并添加所有模板特定的特性,諸如宏等;甚至模板編輯器也是從目標(biāo)語言編輯器產(chǎn)生的,因此你同樣不需要處理代碼
當(dāng)你使用一種模板語言的時(shí)候,你可以認(rèn)為它是用目標(biāo)語言編寫的,只是某些部分的代碼是參數(shù)化的,或者是由宏來計(jì)算的;這種技術(shù)極大的幫助簡(jiǎn)化了代碼生成;模板還可以用在其它任務(wù)上,如重構(gòu)、代碼優(yōu)化、還有更多...
Patterns
模型的模式匹配方法給我們一種作為Model Query Language的代替的查找模型的強(qiáng)大方法;你可以把模式想象成概念模型的正則表達(dá)式;與模板方法類似,我們基于源語言產(chǎn)生模式語言;模式語言看起來像源語言,只是添加了一些特性,來幫助你定義處理復(fù)雜源模型匹配的靈活的標(biāo)準(zhǔn);你可以把這種方法想象成一種強(qiáng)大的“查找替換”的技術(shù);再一次,模式語言不只是對(duì)代碼生成有用,例如,它們?cè)跒樵凑Z言編輯器編寫自動(dòng)化的代碼檢查工具方面非常有用
記住Model Query Language, template languages, 和pattern languages都由強(qiáng)大的編輯器支持其自動(dòng)完成、重構(gòu)、引用檢查、錯(cuò)誤勘測(cè)、等等;即使復(fù)雜的查詢、宏、模式,都可以很容易的編寫;代碼生成從來沒有這么強(qiáng)大過
Using Languages Together
前面有關(guān)代碼生成的章節(jié)帶來了一些關(guān)于這些語言如何一起工作的有意思的問題;事實(shí)上有幾種方法能讓語言一起工作;在MPS中,所有的概念模型都互相知曉;既然語言也是概念模型,那么便意味著所有的語言都彼此知曉,可以潛在的被連接在一起
語言彼此之間可以有不同的關(guān)系;你能夠通過擴(kuò)展現(xiàn)存的語言來創(chuàng)建新語言,繼承所有的概念,修改其中的一些,并加入你自己的概念;一種語言可以引用其它語言中的概念;你甚至能將一種語言插入到另一種語言中去;我將在以后的文章中討論進(jìn)一步的細(xì)節(jié)
Platforms, Frameworks, Libraries, and Languages
我們支持Language Oriented Programming的系統(tǒng)需要比元編程能力更多的功能才能更有用;它應(yīng)該提供程序員依賴于當(dāng)前的編程語言提供的所有事物:集合,用戶界面,網(wǎng)絡(luò),數(shù)據(jù)庫連接,等等;程序員不止是單單基于語言本身來選擇語言;例如,Java的大部分功能不是語言提供的,而是有成千上萬的framework和API供 Java程序員選擇;他們買的不是Java語言,而是整個(gè)Java平臺(tái);MPS也將有一個(gè)它自己的支持平臺(tái)
在我進(jìn)入細(xì)節(jié)前,我們先簡(jiǎn)要談一下frameworks;什么是framework?在主流的編程中,它通常意味著一堆類和方法打包成的一個(gè)類庫;讓我們更近一點(diǎn)的觀察這一點(diǎn),看看在LOP的鏡片下我們會(huì)看到什么
我們?yōu)槭裁聪胍杨惡头椒ù虬蓭炷兀砍绦騿T會(huì)背誦他們的教授曾經(jīng)告訴他們的:“復(fù)用”;但這只是在原來的位置上留下了另一個(gè)問題:我們?yōu)槭裁匆獜?fù)用類庫?答案是類庫在解決特定類型的問題方面很有用,如制作用戶界面,訪問數(shù)據(jù)庫等等;你可以說類庫對(duì)應(yīng)著某個(gè)領(lǐng)域;你瞧,我們看到了聯(lián)系,Class libraries are wannabe DSLs!這個(gè)悲傷的事實(shí)真令我沮喪
今天的Domain-specific languages以類庫的形式存在,除了它們不是語言,沒有語言的優(yōu)勢(shì),并擁有類和方法所有的局限;特別的,類和方法直接綁定到了特定的運(yùn)行時(shí)行為,而特定的運(yùn)行時(shí)行為是不能修改和擴(kuò)展的,因?yàn)樾袨槭翘峁邦悺焙汀胺椒ā钡母拍疃x的;因?yàn)樗鼈儾皇钦Z言,類庫很少被環(huán)境(例如編譯器和編輯器)聰明的支持
我們應(yīng)該忠于wannabe DSLs,還是應(yīng)該擁有當(dāng)需要DSLs的時(shí)候使用真正DSLs的自由?當(dāng)然是自由;每個(gè)類庫都是為我們的平臺(tái)創(chuàng)建一種完全的DSL的候選;例如,JDK的所有類庫都應(yīng)該是MPS平臺(tái)上的DSLs;其中一些DSL在現(xiàn)在剛開始的時(shí)候不是那么緊急需要,但其它一些從一開始就對(duì)平臺(tái)的功能和可復(fù)用性有強(qiáng)烈的影響;我將介紹隨MPS提供的三種最重要的平臺(tái)語言:The Base Language, the Collection Language, and the User Interface Language
Base Language
我們首先需要的語言是對(duì)應(yīng)最簡(jiǎn)單編程領(lǐng)域的,一種general-purpose的命令式編程;這種簡(jiǎn)單的語言應(yīng)該支持近乎通用的語言特性諸如算術(shù)、條件、循環(huán)、函數(shù)、變量等等;在MPS中我們有這樣一種語言,它被稱為Base Language
對(duì)這種語言的需求應(yīng)該是很明顯的,例如,如果我們想把兩個(gè)數(shù)字加在一起,我們應(yīng)該能夠簡(jiǎn)單的說一句“a + b”就可以;我們不需要到處去使用它,但幾乎所有的程序都會(huì)有一些組成部分用到它,在那里,它是完成工作最合適的工具
Base Language之所以如此命名,是因?yàn)樗呛芏嘈枰揪幊讨С秩缱兞俊⒄Z句、循環(huán)等的語言很好的基礎(chǔ);它能夠以三種方式使用:你可以擴(kuò)展它以創(chuàng)建出你自己的基于它的語言,你可以在你的程序中引用它的概念,你還可以以Base Language生成你的代碼;將會(huì)有幾種可用的生成器來將Base Language轉(zhuǎn)換成其它語言如Java,C++等;當(dāng)然,不是每種語言都需要使用Base Language,但是在很多情況下,它是一個(gè)很好的起點(diǎn)
Collection Language
下一種我們需要的最重要的語言是和集合一起工作的語言;對(duì)集合支持的需求是普遍存在的;每種主要的主流語言都提供了對(duì)集合某種類型的支持,例如,在Java 中你有java.util,在C++中你有STL;每個(gè)人都需要集合;如果每種DSL都提供自己的對(duì)集合的支持,那么將會(huì)有a Babylon of不同的集合語言,它們互不兼容;這就是為什么MPS必須提供一種每個(gè)人都使用的單一的Collection Language的原因
在很多主流語言中,集合并非語言特性而是類庫,一個(gè)例子是Java的java.util包;這種支持技術(shù)上來說是存在的,但它是不方便的,雜亂的,并且易于出錯(cuò)的
Yuck!今天大部分的Java代碼被一行接一行多余的、重復(fù)的處理集合的代碼弄的雜亂無章;圖6顯示了一個(gè)例子,Collection Language是如何beats the tar out of a 類庫的;例子是一個(gè)計(jì)算一組給定的點(diǎn)的convex hull的算法;更多關(guān)于Collection Language的細(xì)節(jié)會(huì)在以后的文章中提及
User Interface Language
User Interface Language是我們的平臺(tái)中下一種最重要的DSL;有趣的是,我前面提到的Editor Language能夠另人信服的用來提供用戶界面,但是一種專為圖形用戶界面設(shè)計(jì)的語言將會(huì)更靈活;這種語言帶來的益處是巨大的;Java Swing代碼就是一個(gè)想成為DSL的類庫的極好的例子:功能有了,但很容易被誤用,并且Swing的代碼是徹底雜亂的;很多如今的開發(fā)環(huán)境都包含GUI builder來簡(jiǎn)化用戶界面的創(chuàng)建;User Interface Language將把這項(xiàng)任務(wù)帶到一個(gè)更高的層次;我將在以后的文章中討論更多細(xì)節(jié)
Getting Started with MPS
我已經(jīng)能夠聽到一些對(duì)LOP懷疑的反應(yīng):“聽起來不錯(cuò),但是我們的項(xiàng)目已經(jīng)步入正軌,現(xiàn)在切換到LOP是不可行的”,或者“聽起來不錯(cuò),但用一個(gè)像LOP這樣的未經(jīng)檢驗(yàn)的方法來啟動(dòng)一個(gè)現(xiàn)實(shí)生活中的項(xiàng)目風(fēng)險(xiǎn)太大了”,或者“聽起來不錯(cuò),但是它什么時(shí)候才能為它的黃金時(shí)期做好準(zhǔn)備呢?別忘了OOP用了20年才成為主流”
好消息是我們不需要一頭扎進(jìn)未知里,你可以先用腳趾頭試一下水;你可以在你的項(xiàng)目中只是應(yīng)用LOP的一小塊來看一下它有沒有提供一些實(shí)際的好處,然后如果你喜歡你可以用多一點(diǎn);在不遠(yuǎn)的未來,你可以在MPS里試驗(yàn)兩個(gè)可能的LOP應(yīng)用:
Using MPS on Java Applications
已經(jīng)有一個(gè)IntelliJ IDEA的原型插件允許你在你的項(xiàng)目中包含MPS的概念模型;當(dāng)你編輯模型時(shí),模型會(huì)自動(dòng)在后臺(tái)被轉(zhuǎn)換成Java源代碼;因此,你可以使用MPS來編寫 Java應(yīng)用的部分模塊,喜歡用多點(diǎn)就用多點(diǎn),喜歡用少點(diǎn)就用少點(diǎn);這意味著你得到了MPS全部的力量,比如創(chuàng)建和使用特定DSLs的能力,做任何你想要的語言擴(kuò)展,同時(shí)使用定制的帶有自動(dòng)完成、錯(cuò)誤加亮、重構(gòu)功能的編輯器,等等;插件將和IDEA緊密集成,允許你在你的MPS模型中嵌入Java代碼,導(dǎo)航到嵌入或生成的Java代碼,甚至進(jìn)行概念層次的調(diào)試,就像IDEA中已經(jīng)可用的JSP調(diào)試支持一樣;更多集成特性正在計(jì)劃中;這將是使用IDEA的 Java開發(fā)者可用的一個(gè)重要的新工具
Configuring and Scripting Your Applications
有一個(gè)我見過很多次的模式,一個(gè)應(yīng)用程序啟動(dòng)時(shí)需要某種形式的配置,可能是一個(gè)簡(jiǎn)單的配置文件,或者更完整的部署描述符文件;最后,配置變的更復(fù)雜,應(yīng)用程序最后需要一種腳本語言;對(duì)于簡(jiǎn)單的配置文件,XML很流行;對(duì)于腳本語言,你可以創(chuàng)建自己的,或者借用一種general-purpose的腳本語言,像VBScript,Python/Jyphon,Tcl,Javascript,或者Lisp;這些方案中的每一種都至少有一些主流編程方法的標(biāo)準(zhǔn)缺陷:很長(zhǎng)的實(shí)現(xiàn)時(shí)間,陡峭的學(xué)習(xí)曲線,難以擴(kuò)展,匱乏的環(huán)境支持,等等
作為替代的,你能夠使用MPS創(chuàng)建你自己的配置/腳本語言;你的應(yīng)用程序的用戶將會(huì)擁有一種易于使用的、智能的編輯器來編寫他們的腳本,包括語法加亮,錯(cuò)誤加亮,代碼完成,導(dǎo)航等;只需花費(fèi)很少的時(shí)間來創(chuàng)建并集成這種語言到你的應(yīng)用中;為了使用這種應(yīng)用,你可以分發(fā)MPS的運(yùn)行時(shí)
Conclusion
LOP 和MPS背后的思想并不新鮮,實(shí)際上已經(jīng)出現(xiàn)超過20年了;Language Oriented Programming本身這個(gè)詞也已經(jīng)提出至少10年了;新鮮的是這些思想一直在軟件開發(fā)社區(qū)默默的滲透,而它們的時(shí)代最終到來了;通過這篇文章,我希望提供一顆種子,使這些思想能夠產(chǎn)生新的討論、意見、批評(píng)、實(shí)驗(yàn)、研究、和最終的真實(shí)生活中的項(xiàng)目
并且,因此,我邀請(qǐng)你以任何你能做到的方式參與到這種新的范型中來;在后面添加評(píng)論,或者發(fā)送Email給我:mps_article@jetbrains.com;在http://www.jetbrains.com/mps可找到更多,請(qǐng)關(guān)注更新;注意瀏覽從LOP的視點(diǎn)出發(fā)的網(wǎng)站,雜志,博客,書籍等,并思考事情到底能夠多么簡(jiǎn)單;考慮一下你自己的項(xiàng)目,看看你有多頻繁的實(shí)際上在設(shè)計(jì)和使用小的特定的用類和方法修補(bǔ)的語言;你是怎么認(rèn)為的呢?我想知道
當(dāng)我將LOP的概念用在開發(fā)MPS自身時(shí),我已經(jīng)看到了Language Oriented Programming是如何徹底改進(jìn)軟件開發(fā)的第一手資料;MPS目前并沒有為真實(shí)世界準(zhǔn)備好,但它已經(jīng)成功的達(dá)到了目的;也還依然沒有文檔,除了這篇文章;我將很快的發(fā)布更多的文章,深入的探討MPS;還有,我計(jì)劃下月試驗(yàn)著使MPS可下載,因此你的耳朵要保持張開;已經(jīng)有其它的項(xiàng)目使用了類似的方法,特別是來自Intentional Software 和 Xactium
因此,探險(xiǎn)愉快,讓我看看你能發(fā)現(xiàn)什么
?
Acknowledgements
I would like to thank Rob Harwood for his help in editing this article. I would also like to thank the following people for their reviews, comments, and suggestions: Igor Alshannikov, Florian Hehlen, Jack Herrington, Guillaume
Laforge, Vaclav Pech, Thomas Singer, Dmitry Skavish,David Stennett, and Timur Zambalayev.
About the Author
Sergey Dmitriev (http://www.sergeydmitriev.com) is the co-founder and CEO of JetBrains Inc.(http://www.jetbrains.com), makers of the IntelliJ IDEA Java IDE.
References
Articles:
[1] Donald E. Knuth. Literate programming. The Computer Journal, 27, 97-111, May 1984.
[2] M. Ward. Language Oriented Programming.Software - Concepts and Tools, 15, 147-161 1994,
http://www.dur.ac.uk/martin.ward/martin/papers/middle-out-t.pdf
Intentional Programming articles:
Charles Simonyi. The Death of Computer Languages, The Birth of Intentional Programming. 1995.
ftp://ftp.research.microsoft.com/pub/tr/tr-95-52.doc also
ftp://ftp.research.microsoft.com/pub/tr/tr-95-52.ps
John Brockman. Intentional Programming: A Talk With Charles Simonyi. Edge. 2000.
http://www.edge.org/digerati/simonyi/simonyi_p1.html
Microsoft Research. Intentional Programming.
http://www.cse.unsw.edu.au/~cs3141/ip.asf (video)
Charles Simonyi. Intentional Programming: Asymptotic Fun?http://www.hpcc.gov/iwg/sdp/vanderbilt/position_papers/simonyi.pdf
Books:
Krzysztof Czarnecki and Ulrich W. Eisenecker. Generative Programming: Methods, Tools and Applications.Addison-Wesley, 2000. ISBN: 0201309777.
Jack Herrington. Code Generation in Action. Manning, 2003. ISBN: 1930110979. http://www.codegeneration.net/cgia/
Xactium. Applied Metamodelling: A Foundation for Language Driven Development. 2004.
http://albini.xactium.com/content/index.php?option=com_remository&Itemid=28
Other Resources on the Web:
[3] Matt Quail. Totally Gridbag.
http://madbean.com/blog/2004/17/
Jack Herrington. Code Generation Network.
http://www.codegeneration.net/
[4] Intentional Software
http://www.intentsoft.com
[5] Xactium
http://www.xactium.com
Intentional Programming interviews
Sergey Dmitriev.
http://codegeneration.net/tiki-read_article.php?articleId=60
Charles Symonyi.
http://codegeneration.net/tiki-read_article.php?articleId=61
Krzystof Czarnecki.
http://codegeneration.net/tiki-read_article.php?articleId=64
Andy Evans.
http://codegeneration.net/tiki-read_article.php?articleId=68
See Also:
《Thinking in Current Paradigms, Platforms, Frameworks, and Libraries》
《Thinking in Current Programming Languages》