• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

            巨長的翻譯文章:下一代編程范型主要原則

            LOP : The Next Programming Paradig (ZZ)

            Language Oriented Programming : The Next Programming Paradigm

            Sergey Dmitriev, JetBrains

            本文blog來源:http://www.uuzone.com/blog/oiunt/891/

            現在是軟件開發中開始下一次技術革命的時候了,而這次革命的輪廓正變得越來越清晰。下一代編程范型也在接近我們,但仍然沒有完全成形--不同的部分有不同的名稱:Intentional programming, MDA, generative programming, 等等;我建議把把所有這些新方法歸并為一個名字: ‘language-oriented programming’(面向語言的編程), 而本文將闡述這種新的編程范型的主要原則

            今天主流的編程方法有一些內在的假定像脖子上的繩索一樣桎梏著我們,盡管大部分程序員還沒有意識到它;即使算上在編程領域取得的所有進步,我們也仍然處于石器時代;我們有我們信賴的石斧(面向對象編程),能夠滿足我們的需要,但是當用它來對付最困難的問題時,它會裂成碎屑;為了超越石器前進,我們必須馴服烈火,只有這樣,我們才能鑄造出新的工具,激發一個創作的新時代,和新技術的爆發

            我將討論編程的局限,它強迫程序員像計算機一樣思考,而不是令計算機像程序員一樣思考;這是嚴重的,根深蒂固的局限,需要花費巨大的努力去克服它;當我說這將是編程中下一個大的范型轉換時我并沒有自命不凡;我們需要徹底重新定義我們編寫程序的方法

            本文中,我表述了我的觀點和我當前在Language Oriented Programming (LOP)上的工作;首先我將展示目前主流編程方法的錯誤,然后我會使用示例來解釋LOP的概念,它們基于我已有的一個LOP的實現:the Meta Programming System (MPS). 本文有意只是給你一個對LOP的驚鴻一瞥,目的是激發你對這個思想的興趣,并希望能夠得到反饋和討論

            Part I. LANGUAGE ORIENTED PROGRAMMING OVERVIEW

            Language Oriented Programming and the Meta Programming System

            理想的,做一個程序員意味著我可以對計算機做任何事情,我有完全的自由,完全的控制;但實際上,今天的程序員只有非常受限的自由;當然,我確實可以在計算機上做任何事情,但其中一些事情花費了我許多年的努力,而它們實際上只需要少的多的時間;一定有什么事情不對勁

            程序員被限制是因為他們深深依賴于那些他們不能輕易改變的編程基礎設施:編程語言和開發環境;如果我需要一些語言的擴展,我只能等待語言的設計者去更新它;如果我需要我的IDE有一些額外的強大功能,我只能等待供應商來添加新特性;就是這些依賴限制了我完全的自由;當然,我可以寫我自己的編譯器和IDE,實際上,這也是我啟動了IntelliJ IDEA的原因,因為我厭倦了依賴現有的弱弱的Java IDE;但是,這會花費大量的時間和努力,并且顯而易見,對大部分程序員來說是不可行的;理論上的自由和實際的自由之間存在巨大的差異;下文中當我談到自由時,我指的是實際的自由

            獲得自由的途徑是減少我們的依賴層次;例如,Java的一個主要目標是減少對操作系統的依賴,給開發者在不同操作系統上部署的自由;因此,為了在語言和環境之上獲得自由,我們需要減少對它們的依賴

            為什么這是一個問題呢?任何general-purpose的語言,像Java和C++,給了我們用計算機做任何事情的能力;這是事實,至少理論上是這樣,但是,general-purpose的語言趨向于如同后面我將講到的般生產效率低下;作為一種替代,我們可以使用domain-specific languages(DSLs,aka ‘little languages’),它們被精心設計成在特定問題域具有高度生產率,比如用SQL編寫數據庫查詢;DSLs的強大之處,領域相關,也正是它們的弱處,因為任何真實世界中的程序都會包括許多不同的領域

            general-purpose 和 domainspecific 之間,并不是對立的;我需要所有的自由,我希望能夠做任何事情,同時有很高的生產效率;目前為止還沒有什么好方法能夠做到這點;理想情況下,我能夠為程序的各個特定部分使用不同的語言,而它們能夠融洽的一起工作,并且開發環境會完全支持這些語言,包括重構,代碼補全,導航,以及主流語言具有的所有其它生產力工具

            為了獲得這種獨立性,我需要有創建、重用、修改語言和環境的自由;為了使這種自由是可行的,它需要很容易的被獲得;如果我們解決了易于進行語言和環境的開發的問題,對程序員來說將是一個巨大的進步;這就是Language Oriented Programming的切入點

            要理解Language Oriented Programming是什么,讓我們首先看一下今天的主流編程方法,它基本上是這樣:

            思考: 你需要編程解決一個問題,因此你在你的頭腦里形成了如何解決這個問題的概念模型

            選擇: 你選擇了某種general-purpose的語言來編寫解決方案

            編程: 你通過將你的概念模型艱難的映射到編程語言來編寫解決方案

            編程這一步是瓶頸所在,因為大部分情況映射不是容易的和自然的;這種方法在程序員表達復雜的設計方面已經被證明是低效的;相對的,下面是LOP的工作方式:

            思考: 你需要編程解決一個問題,因此你在你的頭腦里形成了如何解決這個問題的概念模型

            選擇: 你選擇了某些特定的DSLs來編寫解決方案

            創建: 如果沒有合適的DSL適合你的問題,你便創建一種DSL來適應你的問題

            編程: 你通過將你的概念模型相對直接的映射到DSLs來編寫解決方案

            現在,編程這一步is much less of a 瓶頸了,因為DSLs大大簡化了如何將問題翻譯成某種計算機能夠理解的東西;看起來困難已經簡單的轉移到了“創建”這一步,然而,通過聯合使用工具支持和將LOP應用到自身,將使這一步更加簡單

            LOP 背后的動機基本是這樣的:我想用我正試圖解決的問題相關的概念和意圖的詞匯來工作,而不是被迫將我的思想翻譯成某種general-purpose的語言所能理解的概念(比如:類,方法,循環,條件,等等...);為了達到這個目標,我需要使用domain-specific languages;怎樣得到它們呢?創建它們;

            我已經開始開發一個通用的平臺(the Meta Programming System)來設計domainspecific languages,帶有工具支持和開發環境;它將允許程序員像現在編寫程序一樣容易的來定義語言;這個平臺將完全支持LOP,給程序員為程序的每一部分選擇使用最合適的語言的自由,而不是將他們綁在某種固定的general-purpose的編程語言上

            MPS 只是Language Oriented Programming的一個示例,盡管我在這里使用MPS來做示例,而實際上LOP可以用許多不同的方法來實現,你自己就可能知道一些替代方法;LOP 的概念不等同于它的實現,就像OOP的概念不等同于Java或C++或Smalltalk一樣

            What Is Wrong with Mainstream Programming

            你知道這則古老的諺語:"If it ain't broke, don't fix it". 主流編程方法很明顯不完整,我見過它帶來的很多問題,而大部分滋生于這樣一個事實:general-purpose的語言沒有一種方法來完全支持任意的領域,同樣也沒有一種統一的domain-specific language;下面是將被LOP解決的主流編程中三個最糟糕的問題:

            Time Delay to Implement Ideas

            對我來說,最嚴重的問題是,在我確切的知道如何解決一個問題,和我通過一個程序成功的向計算機傳達解決方案之間,有一個很長的時間差;我可以用幾個小時的時間向另外的程序員解釋問題和解決方案,而將解決方案編碼到計算機中將花費長的多的時間;這是因為對另外的程序員,我可以使用表達能力非常豐富的自然語言,而對計算機,我只能使用某種表達能力差很多的general-purpose的編程語言;今天的編程語言只能表達幾十種概念,而自然語言能夠簡潔的表達千萬種概念;因此,向另外的程序員解釋問題,我可以表達很高層的思想,而對計算機,我必須表達每一步的每一個細節

            在主流編程中,大部分花在“編程”上的時間,實際上是在尋找用編程層次的抽象的術語來表達自然語言的概念的方法,而這是很困難的,沒多少創造性的,或多或少是一種時間的浪費

            舉個例子,今天大量的開發時間花費在面向對象的設計(OOD)上,在程序員表達類、繼承、關聯等方面這確實是一種還算有創造性的過程;這項實踐的目的是用面向對象的術語,如類和方法,來表達程序;OOD的過程是必要的,因為諸如類和方法等是面向對象語言能夠理解的僅有的抽象,它看起來是必要和有創造性的,但是使用Language Oriented Programming,OOD根本就不需要

            Understanding and Maintaining Existing Code

            下一個問題是理解和維護現存代碼;不管它是另一個程序員寫的還是我寫的,問題都一樣;因為general-purpose的語言需要我把高層的領域概念翻譯為低層的編程語言特性,在最終的程序中,很多高度概括的視角、藍圖都丟失了;當我在以后重新翻閱程序時,我不得不通過逆向工程來了解我最初的意圖是什么,我頭腦中的模型是什么;至少,我必須在腦海中重新建造最初在翻譯到general-purpose的編程語言的過程中丟失的信息

            解決這個問題的傳統方法是寫注釋或其它形式的文檔來記錄設計信息和模型信息,已經有幾個方面的因素證明了這是一種脆弱的解決方案,至少包括編寫這些輔助文檔的成本、以及文檔和代碼逐漸不同步的趨勢;并且,還有一個沒被廣泛認識到的事實,就是文檔并不能直接連接到它所記錄的概念;注釋和源代碼被綁定到同一個地方,但是概念可能在源代碼的多個地方被表達;其它類型的文檔徹底從源代碼中分離出來,只能間接的引用源代碼;理想情況下,代碼應該是自我描述的,我應該只閱讀代碼本身來理解代碼,而不是什么注釋和外部的文檔

            Domain Learning Curve

            第三個主要的問題是對語言進行領域相關的擴展;例如,在OOP中擴展語言的主要方法是使用類庫;問題是類庫不是用領域概念相關的術語來表達的,而是用低層的 general-purpose的抽象諸如類和方法等來表達;因此,庫很少能夠直接表述領域概念,它們必須引入額外的枝節(如一個類的運行時行為)來完成到領域概念的映射;兩個很好的常見例子是GUI庫和Database庫

            學習這些類庫不是一項簡單的任務,即使你是個領域專家;因為從領域到語言的映射不是直接的,你必須學習這種映射;這意味著一個陡峭的學習曲線;通常我們試圖用大量的指南和文檔來解決這個問題,但是學習這些將花費大量時間;當一個類庫變得復雜的時候,它也變得更難以學習,程序員將因此失去學習它的動機

            甚至當掌握了這種復雜的映射之后,依然還會很容易的誤用類庫,因為開發環境(像編譯器和編輯器)不能幫助你正確的使用類庫,對這些工具來說,調用一個GUI 對象的方法和調用一個DB對象的方法是一樣的:它們都只是對象上的方法調用,沒有任何更多的意思;記住哪些類和方法應該被調用,以什么順序被調用,等等,都是使用者的責任

            甚至即使你既是領域專家又是類庫的使用專家,也仍然有使用類庫編寫的程序十分冗長的問題;相對簡單的領域概念需要復雜的措施來正確的調用;例如,任何用過Swing的開發者都清楚這一點;編寫簡單的程序就已經花費太長的時間了,復雜的程序甚至更糟

            Details of LOP

            What Is a Program in LOP?

            今天,百分之九十九的程序員認為編程就是編寫一串計算機能夠執行的指令集;我們被教育說計算機建立在圖靈機模型之上,因此它們用指令集的術語來“思考”;但是這種編程的觀點是有缺陷的,它混淆了編程的目的和手段;我將為你演示LOP為什么優于傳統編程方法,但首先我必須澄清以下事實:一個LOP的程序,不是一串指令集;那么它是什么呢?

            當我有一個問題要解決,我在頭腦中思考解決方案,這個解決方案用單詞、標記、概念、思想,或者任何你喜歡的稱呼來表述,它是我頭腦中如何解決問題的模型;我幾乎從未把它們想象成一堆指令集,而是我正在工作的領域中特定的具有內在聯系的概念的集合;例如,當我思考GUI領域時,我想象“這個按鈕到那邊去,這個輸入域到這邊來,這個組合框里面需要有一些數據的列表”;我甚至只是在頭腦中把它畫出來,根本不用任何言語

            我之所以認為這種意念模型是一種解決方案是因為我能夠用足夠的細節向另一個程序員解釋這個模型,使他能夠坐下來編寫一個解決這個問題的程序(比如用 Java);我不需要非得用編程語言的術語來解釋這個方案,它可以是任意形式;比如,為了解釋如何布局一個GUI的窗體,我只需要畫出這個窗體;如果繪畫有足夠的細節,繪畫本身就代表了解決方案;這種領域相關的表述應該就是程序。換句話說,應該有一種方法允許我們使用這種表述作為真正的程序,而不僅僅是與其它程序員交流的手段;于是這便導出了我對程序非正式的定義:一個程序是任何對一個問題無歧義的解決方案,或者,更精確一點:一個程序是對某個領域的某個問題的解決方案的任何使用領域相關概念表達的,精確定義的模型

            這就是我認為程序員應該擁有創建他們自己的語言的自由的主要原因:這樣他們就能夠用更加自然的形式來表達解決方案;General-purpose的語言是無歧義的,但是太冗余和易于出錯;自然語言(如英語)表達能力十分豐富,但目前它難以使用因為它太不精確太不形式化了;我們需要能夠容易的創建形式化的,精確定義的,領域相關的語言;因此Language Oriented Programming將不只是編寫程序,還包括創建用來編寫程序的語言;我們的程序將被編寫的更接近問題域而不是計算機指令集領域,因此它們將非常容易的被編寫

            Programs and Text

            人們習慣性的認為程序是作為文本來存儲的,也就是說,一個字節流;為什么不應該是呢?畢竟有無數的工具來編輯、顯示、操作文本;今天的編程語言的核心部分是文法器,解析器,編譯器和面向行的調試器;但是程序的文本只是程序的一種表現形式;程序不是文本;強行把程序塞到文本里引起了大量你可能還不知道的問題;我們需要一種不同的方法來存儲并和我們程序一起工作

            當編譯器編譯源代碼時,它把文本解析成稱作抽象語法樹的樹狀結構;當程序員閱讀源代碼時,他們在腦海中做了本質上相同的事情;我們仍然不得不考慮程序的樹狀結構;這就是為什么我們要有花括號,方括號,圓括號等;這也是為什么我們需要格式化和縮進代碼和遵守編碼規范,因為這樣就能夠更容易的閱讀源代碼

            我們為什么使用文本存儲呢?因為當前,閱讀和編輯程序最方便和最通用的方法還是使用文本編輯器;但是我們會為此付出代價,因為程序的文本表示有重大的缺點,其中最重要的是基于文本的編程語言非常難于擴展;如果程序以文本的形式存儲,你就會需要一個無歧義的文法器來解析程序;當為語言加入新特性時,維護語言無二義性的擴展變得日益困難;我們將需要發明更多類型的括號、操作符、關鍵字、順序規則、嵌套,等等;語言的設計者們花費了無數時間來思考語法,并試圖發現擴展語言的新方法

            如果我們打算讓創建語言變得容易,我們就需要將程序的表示和存儲從程序本身分離開;我們應該直接將程序存為結構圖,因為這允許我們對語言做任何我們喜歡的擴展;有時,我們甚至根本不需要考慮文本存儲;今天的一個很好的例子是Excel spreadsheet.百分之九十九的人根本不需要處理存儲格式,當這成為問題時總會有各種導入導出功能可用;今天我們使用文本的真正原因是我們沒有比文本編輯器更好的編輯器,但是我們可以改變這一點

            問題是文本編輯器很愚蠢,并且不知道如何與程序的圖狀結構一起工作;但是使用正確的工具,編輯器將能夠直接和圖狀結構一起工作,并且能夠讓我們自由的使用任何編輯器提供的我們喜歡的可視化表現形式;我們可以把程序做成文本、表、圖、樹、或其它任何形式;我們甚至能為不同目的使用不同的表現形式,比方說,圖形化表示用來瀏覽,文本化表示用來編輯;我們能夠為代碼的不同部分使用領域相關的表示,比如為數學公式使用圖形化的數學符號,為圖表使用圖形化的圖表,為 spreadsheets使用行和列,等等;我們能夠為問題域使用最合適的表現形式,可以是文本,但不限于文本;最好的表現形式依賴于我們如何思考問題域;表現形式的靈活性也將使我們的編輯器比以往更加強大,因為不同的表現形式有不同的方式去編輯它們

            What Is a Language in LOP?

            最后,我應該闡明我認為的“語言”是什么;在LOP中,一種語言是通過三個主要的要素來定義的:結構、編輯器、和語義;結構定義了抽象語法、支持的概念、以及如何安排它們;編輯器定義了具體的語法,如何描繪和編輯語言;語義定義了行為,它如何被解釋,和/或它如何被轉換成可執行代碼;當然,語言還可以有其它方面,比如約束和類型系統

            Part II. INTRODUCTION TO META PROGRAMMING SYSTEM

            Creating Languages in MPS

            我已經解釋了為什么我們需要容易的創建新的語言,但是,我們如何才能讓它容易呢?如果你turn around這個問題,并且把Language Oriented Programming應用于它自身,你會很快看到答案;This calls for a little self-referential bootstrapping, which can seem tricky, but be patient. 一旦你理解了這個,你將得到LOP真正的力量(一個LOP的元層次)

            回顧一下LOP的理念:使創建DSLs更容易,而這些DSLs將使編寫程序更容易;但就像我已經說明的,LOP中的‘程序’不局限的意味著你用過的典型的 “一堆指令集”的程序;對某個領域中某個問題任何無二義性的解決方案都是‘程序’;因此如果你設想一下“創建新語言”這個領域,那么這個領域中的‘程序 ’,本身就是一種新語言的定義,可以作為一個解決方案來思考,就像任何其它領域的解決方案一樣;

            因此,應用LOP的思想,使“創建新語言”更容易的方法,就是創建一種特定的專注于“創建新語言”這個領域的DSL;通過應用這些language- building DSL,我們可以使制造新語言更容易;讓我們看幾種language-building語言的例子,使你更好的理解它們是如何工作的;這里只是一個概述,以后的文章我會更詳細的描述它們

            Structure Language

            最小最少,我們需要定義新語言的‘結構’;這是我們何以能夠編寫“精確定義”的程序的原因;語言的結構并不意味著它的文本形式的文法--像我提到過的,這種語言甚至根本就沒有文本表示而只有圖形化表示

            在實踐LOP的時候,大部分情況下,你會工作在兩個層次的編程中:元層次和程序層次;你在元層次中定義語言,在程序層次中編寫程序;當定義一種新語言的結構時,你會使用一種language-structure DSL來定義你的新語言,而這時,你將同時工作在這種language-structure DSL的程序層次和新語言的元層次中

            在MPS 中,程序層次的每個節點都有一種“類型”,簡單的連接到元層次的另一個節點;程序層次的這個節點被稱作這種類型的一個“實例”;元層次中的“類型”節點則定義了這種類型的實例能夠擁有的關系和屬性;描述這種元層次語言結構的語言,就被簡單的稱為“Structure Language”

            用Structure Language定義一種語言的抽象語法,你應該只是枚舉這種語言所有的類型;類型簡單的表示了這種語言支持的特性或者概念;每個概念應該用它的名字、實例的內部屬性、實例與其它節點之間的關系(通常是連接)來定義

            存在兩種可能的關聯;第一種是類似聚合的關聯,它形成了概念模型的父子樹結構;第二種是非聚合的,自由形式的關聯,它可以連接到系統中任何其它的節點;關聯有兩個端點:源和目標;關聯有角色,你可以定義每個角色的名稱、每個端點的多重性,每個目標節點的類型;多重性可以是1, 0..1, 0..n, 1..n等,讓你能夠約束關聯可以創建多少連接;關聯的目標類型可以被用來約束哪些類型的節點可以被連接在一起

            因此,使用新語言編寫程序包括:創建語言中概念的實例、為實例的屬性賦值、根據語言概念定義的關系將程序中的節點連接在一起;所有這些將會被強大的編輯器支持,你能夠為你的語言定義這種編輯器

            Editor Language

            那么,編寫和操作概念模型的界面應該是什么呢?我們的語言需要幾種類型的編輯器,但是我們不想要一個通用的編輯器;經驗表明通用的編輯器不能像我們希望的那樣有用;我們希望快速的編寫模型,因此我們需要專為我們的語言概念定做的特殊的編輯器;一定程度上,編輯器是語言的一部分,而我們的目標是容易的創建新語言,那么創建新的編輯器也應該很容易;本質上,我們需要一種創建編輯器的語言,在MPS中,它被稱為Editor Language

            當人們聽我說我們的程序將存儲為圖形并且我們需要特定的編輯器,我確信很多人認為我將要談到圖形編輯器,事實不是這樣子的;盡管程序是圖形形式,編輯器卻不一定非得將程序描繪成圖形;事實上,只有少數情況下圖形編輯器才是有用的(也就是說,當它合適的時候,比如對數據庫表);相反,我們的Editor Language有更好的靈感來源,諷刺的是,它來自文本編輯器

            如果你用文本編輯器瀏覽一個典型的程序,你可以想象編輯器被分成了矩形單元;一些單元包含必需的標識如關鍵字、花括號、圓括號等,其它的單元包含用戶定義的標識,如類和方法的名稱;大的單元由小的單元組成,像方法塊包含語句,而語句可能包含自己的嵌套塊;事實上,任何主流編程語言中任何良好構造的程序都可以分解為矩形單元的集合;那么,在Editor Language中,你不需要想象這些單元,因為編輯器就是簡單的由矩形單元組成的

            單元的使用有一些有趣的優點;首先,當直接工作在程序圖形而不是程序文本上時,單元可以完美的模仿甚至超過標準的文本編輯器;第二,單元不局限于文本,你可以往單元里塞進顏色選擇器、數學符號、圖表、矢量圖、或任何別的什么;最后,這種單元形式的layout是可選的,程序員可以提供不同的機制,單元形式的 layout只是一種有用的缺省設置

            因此,Editor Language幫助你定義語言中每個概念對應的單元的layout;你可以定義哪些部分是不變的,像括號或其它修飾符號,哪些是可變的,需要用戶去定義的;Editor Language也幫助你在你自己的編輯器中加入強大的特性,像自動完成、重構、導航、語法加亮、錯誤加亮、以及任何其它你想到的事情;因此你能夠增加現在的編輯器如IntelliJ IDEA等擁有的功能到你自己的語言中;這是可能的,因為程序和語言被構造為圖形,而我們有專門的Editor Language幫助我們創造強大的編輯器

            Transformation Language

            Structure Language和Editor Language已經共同提供了一些功能,你能夠用它們和其他人交流思想,比如畫UML圖,或者編寫其它類型的文檔;然而,大部分時間我們是想讓我們的代碼做點什么,因此,我們必須找到一種方法讓它能夠執行;有兩種主要的方式來做這件事情:解釋和編譯

            DSLs支持的解釋方式幫助定義計算機應該如何解釋程序,DSLs支持的編譯方式幫助定義如何為程序產生可執行代碼;我將在以后的文章中討論對解釋方式的支持,現在我想說明一下MPS是如何支持編譯方式的

            編譯意味著拿到源代碼,并從中產生某種形式的可執行代碼;對于結果代碼有多種可能的形式;為產生可執行代碼,你可以生成本地機器碼,也可以生成虛擬機字節碼;或者,你可以生成另外一種語言的源代碼(比如Java,C++),然后用現有的編譯器轉換為可執行代碼;類似的,你甚至可以產生某種解釋型語言的源代碼,用現有的解釋器解釋執行

            為了避免處理這么廣泛的目標格式,我們的方法是用MPS來做每一件事;首先,你在MPS中使用Structure Language定義一種目標語言,這種目標語言和目標格式之間應該有直接的一對一的映射;例如,如果你的目標格式是機器碼,你應該用MPS定義一種對應機器碼的目標語言;如果目標格式是Java源代碼,你應該定義一種類Java的目標語言;目標語言不必支持目標格式所有的功能特性,只為你需要的語言特性進行簡單的一對一的映射即可

            那么現在,編譯分為兩個階段:一個簡單的從目標語言到最終結果的翻譯,一個更復雜的從最初的原始語言到中間目標語言的轉換;翻譯階段是微不足道的,因此我們把精力集中于更有意思的轉換階段;至少,現在的問題簡化為了如何將模型從一種語言轉換到另一種語言;但是,有可能源語言與目標語言是完全不同的,導致轉換非常復雜,比如映射一個源節點到許多散布在目標模型中的目標節點;我們想讓定義轉換盡可能的簡單容易,因此我們需要一種模型轉換DSL來幫助我們;在MPS中,這種 DSL被稱為Transformation Language

            代碼生成有三種主要的方法,我們將結合使用它們來定義模型轉換;第一種是遍歷方式,你枚舉源模型中所有節點,檢視每一個,并基于檢視到的信息生成目標模型中的一些目標節點;第二種方式是使用模板和宏來定義如何生成目標語言;第三種方式是使用模式匹配來查找在源模型中的哪些節點上應用轉換

            我們通過定義DSLs把這些方式結合起來以支持任何一種方法;這些DSLs將一起工作來幫助你定義從一種語言到另一種語言的轉換;例如,遍歷方式激發了 Model Query Language的靈感,它使枚舉節點和從概念模型中收集信息變得簡單容易;你可以把它想象成某種針對概念模型的SQL;做為一種額外的獎賞,擁有一種強大的查詢語言不只是對代碼生成有用(例如,能夠使編輯器更聰明)

            Templates

            模板方法工作方式類似Velocity或者XSLT;模板看起來很像目標語言,但是允許你在模板的任何部分中添加宏;宏本質上是當運行轉換的時候被執行的代碼段;宏允許你檢視源模型(使用Model Query Language),并使用得到的信息對模板進行“填空”,得到最終的目標代碼

            在圖5中,你可以看到為概念“Property”生成Java代碼的模板的定義,模板為屬性添加了field declarations, getters, setters等;這個模板是將代碼從Structure Language轉換為Java的生成器的一部分

            既然模板看起來像目標語言,你可以想象模板是用某種基于目標語言的特殊的語言編寫的;這也是它事實上的工作方式;我們實際上使用一個生成器來為你生成模板語言,而不是手工為每一種可能的目標語言創建模板語言;它基本上是復制目標語言,并添加所有模板特定的特性,諸如宏等;甚至模板編輯器也是從目標語言編輯器產生的,因此你同樣不需要處理代碼

            當你使用一種模板語言的時候,你可以認為它是用目標語言編寫的,只是某些部分的代碼是參數化的,或者是由宏來計算的;這種技術極大的幫助簡化了代碼生成;模板還可以用在其它任務上,如重構、代碼優化、還有更多...

            Patterns

            模型的模式匹配方法給我們一種作為Model Query Language的代替的查找模型的強大方法;你可以把模式想象成概念模型的正則表達式;與模板方法類似,我們基于源語言產生模式語言;模式語言看起來像源語言,只是添加了一些特性,來幫助你定義處理復雜源模型匹配的靈活的標準;你可以把這種方法想象成一種強大的“查找替換”的技術;再一次,模式語言不只是對代碼生成有用,例如,它們在為源語言編輯器編寫自動化的代碼檢查工具方面非常有用

            記住Model Query Language, template languages, 和pattern languages都由強大的編輯器支持其自動完成、重構、引用檢查、錯誤勘測、等等;即使復雜的查詢、宏、模式,都可以很容易的編寫;代碼生成從來沒有這么強大過

            Using Languages Together

            前面有關代碼生成的章節帶來了一些關于這些語言如何一起工作的有意思的問題;事實上有幾種方法能讓語言一起工作;在MPS中,所有的概念模型都互相知曉;既然語言也是概念模型,那么便意味著所有的語言都彼此知曉,可以潛在的被連接在一起

            語言彼此之間可以有不同的關系;你能夠通過擴展現存的語言來創建新語言,繼承所有的概念,修改其中的一些,并加入你自己的概念;一種語言可以引用其它語言中的概念;你甚至能將一種語言插入到另一種語言中去;我將在以后的文章中討論進一步的細節

            Platforms, Frameworks, Libraries, and Languages

            我們支持Language Oriented Programming的系統需要比元編程能力更多的功能才能更有用;它應該提供程序員依賴于當前的編程語言提供的所有事物:集合,用戶界面,網絡,數據庫連接,等等;程序員不止是單單基于語言本身來選擇語言;例如,Java的大部分功能不是語言提供的,而是有成千上萬的framework和API供 Java程序員選擇;他們買的不是Java語言,而是整個Java平臺;MPS也將有一個它自己的支持平臺

            在我進入細節前,我們先簡要談一下frameworks;什么是framework?在主流的編程中,它通常意味著一堆類和方法打包成的一個類庫;讓我們更近一點的觀察這一點,看看在LOP的鏡片下我們會看到什么

            我們為什么想要把類和方法打包成庫呢?程序員會背誦他們的教授曾經告訴他們的:“復用”;但這只是在原來的位置上留下了另一個問題:我們為什么要復用類庫?答案是類庫在解決特定類型的問題方面很有用,如制作用戶界面,訪問數據庫等等;你可以說類庫對應著某個領域;你瞧,我們看到了聯系,Class libraries are wannabe DSLs!這個悲傷的事實真令我沮喪

            今天的Domain-specific languages以類庫的形式存在,除了它們不是語言,沒有語言的優勢,并擁有類和方法所有的局限;特別的,類和方法直接綁定到了特定的運行時行為,而特定的運行時行為是不能修改和擴展的,因為行為是提供“類”和“方法”的概念定義的;因為它們不是語言,類庫很少被環境(例如編譯器和編輯器)聰明的支持

            我們應該忠于wannabe DSLs,還是應該擁有當需要DSLs的時候使用真正DSLs的自由?當然是自由;每個類庫都是為我們的平臺創建一種完全的DSL的候選;例如,JDK的所有類庫都應該是MPS平臺上的DSLs;其中一些DSL在現在剛開始的時候不是那么緊急需要,但其它一些從一開始就對平臺的功能和可復用性有強烈的影響;我將介紹隨MPS提供的三種最重要的平臺語言:The Base Language, the Collection Language, and the User Interface Language

            Base Language

            我們首先需要的語言是對應最簡單編程領域的,一種general-purpose的命令式編程;這種簡單的語言應該支持近乎通用的語言特性諸如算術、條件、循環、函數、變量等等;在MPS中我們有這樣一種語言,它被稱為Base Language

            對這種語言的需求應該是很明顯的,例如,如果我們想把兩個數字加在一起,我們應該能夠簡單的說一句“a + b”就可以;我們不需要到處去使用它,但幾乎所有的程序都會有一些組成部分用到它,在那里,它是完成工作最合適的工具

            Base Language之所以如此命名,是因為它是很多需要基本編程支持如變量、語句、循環等的語言很好的基礎;它能夠以三種方式使用:你可以擴展它以創建出你自己的基于它的語言,你可以在你的程序中引用它的概念,你還可以以Base Language生成你的代碼;將會有幾種可用的生成器來將Base Language轉換成其它語言如Java,C++等;當然,不是每種語言都需要使用Base Language,但是在很多情況下,它是一個很好的起點

            Collection Language

            下一種我們需要的最重要的語言是和集合一起工作的語言;對集合支持的需求是普遍存在的;每種主要的主流語言都提供了對集合某種類型的支持,例如,在Java 中你有java.util,在C++中你有STL;每個人都需要集合;如果每種DSL都提供自己的對集合的支持,那么將會有a Babylon of不同的集合語言,它們互不兼容;這就是為什么MPS必須提供一種每個人都使用的單一的Collection Language的原因

            在很多主流語言中,集合并非語言特性而是類庫,一個例子是Java的java.util包;這種支持技術上來說是存在的,但它是不方便的,雜亂的,并且易于出錯的

            Yuck!今天大部分的Java代碼被一行接一行多余的、重復的處理集合的代碼弄的雜亂無章;圖6顯示了一個例子,Collection Language是如何beats the tar out of a 類庫的;例子是一個計算一組給定的點的convex hull的算法;更多關于Collection Language的細節會在以后的文章中提及

            User Interface Language

            User Interface Language是我們的平臺中下一種最重要的DSL;有趣的是,我前面提到的Editor Language能夠另人信服的用來提供用戶界面,但是一種專為圖形用戶界面設計的語言將會更靈活;這種語言帶來的益處是巨大的;Java Swing代碼就是一個想成為DSL的類庫的極好的例子:功能有了,但很容易被誤用,并且Swing的代碼是徹底雜亂的;很多如今的開發環境都包含GUI builder來簡化用戶界面的創建;User Interface Language將把這項任務帶到一個更高的層次;我將在以后的文章中討論更多細節

            Getting Started with MPS

            我已經能夠聽到一些對LOP懷疑的反應:“聽起來不錯,但是我們的項目已經步入正軌,現在切換到LOP是不可行的”,或者“聽起來不錯,但用一個像LOP這樣的未經檢驗的方法來啟動一個現實生活中的項目風險太大了”,或者“聽起來不錯,但是它什么時候才能為它的黃金時期做好準備呢?別忘了OOP用了20年才成為主流”

            好消息是我們不需要一頭扎進未知里,你可以先用腳趾頭試一下水;你可以在你的項目中只是應用LOP的一小塊來看一下它有沒有提供一些實際的好處,然后如果你喜歡你可以用多一點;在不遠的未來,你可以在MPS里試驗兩個可能的LOP應用:

            Using MPS on Java Applications

            已經有一個IntelliJ IDEA的原型插件允許你在你的項目中包含MPS的概念模型;當你編輯模型時,模型會自動在后臺被轉換成Java源代碼;因此,你可以使用MPS來編寫 Java應用的部分模塊,喜歡用多點就用多點,喜歡用少點就用少點;這意味著你得到了MPS全部的力量,比如創建和使用特定DSLs的能力,做任何你想要的語言擴展,同時使用定制的帶有自動完成、錯誤加亮、重構功能的編輯器,等等;插件將和IDEA緊密集成,允許你在你的MPS模型中嵌入Java代碼,導航到嵌入或生成的Java代碼,甚至進行概念層次的調試,就像IDEA中已經可用的JSP調試支持一樣;更多集成特性正在計劃中;這將是使用IDEA的 Java開發者可用的一個重要的新工具

            Configuring and Scripting Your Applications

            有一個我見過很多次的模式,一個應用程序啟動時需要某種形式的配置,可能是一個簡單的配置文件,或者更完整的部署描述符文件;最后,配置變的更復雜,應用程序最后需要一種腳本語言;對于簡單的配置文件,XML很流行;對于腳本語言,你可以創建自己的,或者借用一種general-purpose的腳本語言,像VBScript,Python/Jyphon,Tcl,Javascript,或者Lisp;這些方案中的每一種都至少有一些主流編程方法的標準缺陷:很長的實現時間,陡峭的學習曲線,難以擴展,匱乏的環境支持,等等

            作為替代的,你能夠使用MPS創建你自己的配置/腳本語言;你的應用程序的用戶將會擁有一種易于使用的、智能的編輯器來編寫他們的腳本,包括語法加亮,錯誤加亮,代碼完成,導航等;只需花費很少的時間來創建并集成這種語言到你的應用中;為了使用這種應用,你可以分發MPS的運行時

            Conclusion

            LOP 和MPS背后的思想并不新鮮,實際上已經出現超過20年了;Language Oriented Programming本身這個詞也已經提出至少10年了;新鮮的是這些思想一直在軟件開發社區默默的滲透,而它們的時代最終到來了;通過這篇文章,我希望提供一顆種子,使這些思想能夠產生新的討論、意見、批評、實驗、研究、和最終的真實生活中的項目

            并且,因此,我邀請你以任何你能做到的方式參與到這種新的范型中來;在后面添加評論,或者發送Email給我:mps_article@jetbrains.com;在http://www.jetbrains.com/mps可找到更多,請關注更新;注意瀏覽從LOP的視點出發的網站,雜志,博客,書籍等,并思考事情到底能夠多么簡單;考慮一下你自己的項目,看看你有多頻繁的實際上在設計和使用小的特定的用類和方法修補的語言;你是怎么認為的呢?我想知道

            當我將LOP的概念用在開發MPS自身時,我已經看到了Language Oriented Programming是如何徹底改進軟件開發的第一手資料;MPS目前并沒有為真實世界準備好,但它已經成功的達到了目的;也還依然沒有文檔,除了這篇文章;我將很快的發布更多的文章,深入的探討MPS;還有,我計劃下月試驗著使MPS可下載,因此你的耳朵要保持張開;已經有其它的項目使用了類似的方法,特別是來自Intentional Software 和 Xactium

            因此,探險愉快,讓我看看你能發現什么

            ?

            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

            posted on 2006-05-24 09:04 夢在天涯 閱讀(814) 評論(2)  編輯 收藏 引用 所屬分類: software engine

            評論

            # re: 巨長的翻譯文章:下一代編程范型主要原則 2006-06-01 21:48 cilong521

            實際上文中的觀點不能算是創新,它只是對現在的一些做法形式化了而已。而且所謂創建DSLs的做法,作者唯一的優勢也許就是他的平臺可以讓我們做這件事情比現在用perl等語言編寫一個DSL更容易一些,也許就是因為作者的平臺使我們不用太多的考慮二義性等問題。  回復  更多評論   

            # re: 巨長的翻譯文章:下一代編程范型主要原則 2008-07-26 03:49 冷不防

            謝謝!!!!  回復  更多評論   

            公告

            EMail:itech001#126.com

            導航

            統計

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1804363
            • 排名 - 5

            最新評論

            閱讀排行榜

            精品无码人妻久久久久久| 国产91色综合久久免费| 久久久精品久久久久久| 日韩中文久久| 久久久久久九九99精品| 91亚洲国产成人久久精品网址| 精品久久久久久无码国产 | 亚洲第一极品精品无码久久| 精品久久久久中文字幕日本| 精品免费久久久久国产一区| 伊人久久大香线蕉综合Av| 2020最新久久久视精品爱| 99久久这里只精品国产免费| 91精品国产综合久久婷婷| 欧美伊人久久大香线蕉综合| 青青草国产成人久久91网| 97视频久久久| 久久人人爽人人精品视频| 久久亚洲国产精品一区二区| 日韩精品久久久久久免费| 天堂无码久久综合东京热| 久久er热视频在这里精品| 久久久久久无码Av成人影院| 欧美黑人激情性久久| 久久99精品国产99久久6| 97久久精品无码一区二区天美| 国产精品99久久久精品无码| 久久久久亚洲AV成人网人人网站 | 久久精品无码专区免费| 久久久精品一区二区三区| 天堂久久天堂AV色综合| 亚洲日本va午夜中文字幕久久| 国产亚洲精久久久久久无码AV| 精品一区二区久久久久久久网站| 色婷婷综合久久久中文字幕| 中文字幕久久波多野结衣av| 热99RE久久精品这里都是精品免费| 热久久国产欧美一区二区精品| 日韩中文久久| 亚洲午夜久久久影院| 伊人久久综合无码成人网|