版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、綜述:編程語言的發(fā)展趨勢及未來方向2010-08-30 12:27 by Jeffrey Zhao, 7089 visits, 網(wǎng)摘, 收藏, 編輯 這是一篇發(fā)表在程序員雜志8月刊的文章,是根據(jù)我對Anders Hejlsberg的演講內(nèi)容的翻譯的縮寫。原本的完整演講內(nèi)容有數(shù)萬字,為了在雜志上發(fā)表因此簡化成了五千字,因此如果您對完整內(nèi)容感興趣,不妨根據(jù)文末鏈接來訪問完整內(nèi)容,其中也包含大量分解的幻燈片以及代碼。概述程序設(shè)計離不開編程語言,但是編程語言在國內(nèi)的大環(huán)境中似乎一直是個二等公民。國內(nèi)的計算機教育和工程培訓(xùn),似乎一直在宣傳“語言不重要,重要的是思想”,“語言一通百通”等觀點,甚至在許多人
2、眼中“語言的討論”完全是不入流的,但其實“編程語言”與“工具”、“框架”或是“開發(fā)方法”等事物一樣,都對生產(chǎn)力有著重要的影響。事實上,語言的發(fā)展歷史比其他方面更為悠久,并且在過去十幾年,甚至最近幾年中都依然在不斷的碰撞,演變。期間一些新的語言誕生了,而另一些在當時看來陽春白雪的語言和編程范式也重新獲得了人們的重視。Anders Hejlsberg是微軟的Technical Fellow,擔任C#編程語言的首席架構(gòu)師,也參與了.NET Framework,以及VB.NET和F#等語言的設(shè)計與開發(fā)。幾個月前,Anders在比利時的TechDays 2010及荷蘭DevDays 2010分別進行了一
3、場演講,闡述了他眼中對于編程語言的發(fā)展趨勢及未來方向,本文便對他的觀點進行了總結(jié)。大約25到30年前,Anders開發(fā)了著名的Turbo Pascal,這是一套集語言、編譯器及開發(fā)工具于一體的產(chǎn)品,這也是Anders進入編程語言這一領(lǐng)域的起點。Anders談到,如今的計算機和當年他開發(fā)的Turbo Pascal所用的Z-80已經(jīng)不可同日而語。從那時算起,如今的機器已經(jīng)有大約10萬倍的外部存儲容量,1萬倍的內(nèi)存大小,CPU速度也有大約1000倍的提高。但是,如果我們比較如今的Java代碼及當年P(guān)ascal代碼,會發(fā)現(xiàn)它們的差別其實并不大。Anders認為編程語言的發(fā)展非常緩慢,期間當然出現(xiàn)了一些
4、東西,例如面向?qū)ο蟮鹊?,但是遠沒有好上1000倍。事實上,近幾十年來的努力主要體現(xiàn)在框架及工具等方面(如下圖)。例如.NET Framework里有超過一萬個類及十萬個方法,與Turbo Pascal相比的確有了超過1000倍的增長。同樣類似,現(xiàn)在的IDE包含了無數(shù)強大的功能,例如語法提示,重構(gòu),調(diào)試器等等。與此相比,編程語言的改進的確很不明顯。在過去5、60年的編程歷史中,編程語言的抽象級別不斷提高,人們都在努力讓編程語言更有表現(xiàn)力,這樣我們可以用更少的代碼完成更多的工作。我們一開始使用匯編,然后使用面向過程的語言(如Pascal和C),然后是面向?qū)ο笳Z言(如C+),隨后便進入了托管時代,語
5、言運行于受托管的執(zhí)行環(huán)境上(如C#,Java),它們的主要特性有自動的垃圾收集,類型安全等等。Anders認為這樣的趨勢還會繼續(xù)保持下去,我們還會看到抽象級別越來越高的語言,而語言的設(shè)計者則必須理解并預(yù)測下一個抽象級別是什么樣子的。另一方面,如.NET,Java等框架的重要性提高了許多,編程語言往往都傾向于構(gòu)建于現(xiàn)有的工具上,而不會從頭寫起?,F(xiàn)在出現(xiàn)的編程語言,例如F#,以及Java領(lǐng)域的Scala,Clojure等等,它們都是基于現(xiàn)有框架構(gòu)建的,每次從頭開始的代價實在太高。在Anders眼中,如今影響力較大的趨勢主要有三種(如下圖),它們分別是“聲明式的編程風格”(包括“領(lǐng)域特定語言”及“函
6、數(shù)式編程”)、過去的五年非?;馃岬摹皠討B(tài)語言”(其最重要的方面便是“元編程”能力)以及多核環(huán)境下的“并發(fā)編程。此外隨著語言的發(fā)展,原本常用的“面向?qū)ο蟆闭Z言,“動態(tài)語言”或是“函數(shù)式”等邊界也變得越來越模糊,例如各種主要的編程語言都受到函數(shù)式語言的影響。因此,“多范式”程序設(shè)計語言也是一個愈發(fā)明顯的趨勢。聲明式編程與DSL目前常見的編程語言大都是命令式(Imperative)的,例如C#,Java或是C+等等。這些語言的特征在于,代碼里不僅表現(xiàn)了“做什么(What)”,而更多表現(xiàn)出“如何(How)完成工作”這樣的實現(xiàn)細節(jié),例如for循環(huán),i += 1等等,甚至這部分細節(jié)會掩蓋了我們的“最終目標
7、”。在Anders看來,命令式編程通常會讓代碼變得十分冗余,更重要的是由于它提供了過于具體的指令,這樣執(zhí)行代碼的基礎(chǔ)設(shè)施(如CLR或JVM)沒有太多發(fā)揮空間,只能老老實實地根據(jù)指令一步步的向目標前進。例如,并行執(zhí)行程序會變得十分困難,因為像“執(zhí)行目的”這樣更高層次的信息已經(jīng)丟失了。因此,編程語言的趨勢之一,便是能讓代碼包含更多的“What”,而不是“How”,這樣執(zhí)行環(huán)境便可以更加聰明地去適應(yīng)當前的執(zhí)行要求。關(guān)于聲明式的編程風格,Anders主要提出了兩個方面,第一個方面是DSL(Domain Specific Language,領(lǐng)域特定語言)。DSL不是什么新鮮的玩意兒,我們平時經(jīng)常接觸的S
8、QL,CSS,正則表達式等等都屬于DSL。有的DSL可能更加專注于一個方面,例如Mathematica,LOGO等等。這些語言的目標都是特定的領(lǐng)域,與之相對的則是GPPL(General Purpose Programming Language,通用目的編程語言)。Martin Fowler將DSL分為外部DSL及內(nèi)部DSL兩種。外部DSL有自己的特定語法、解析器和詞法分析器等等,它們往往是一種小型的編程語言,甚至不會像GPPL那樣需要源文件。與之相對的則是內(nèi)部DSL。內(nèi)部DSL其實更像是種別稱,它代表一類特別API及使用模式。XSLT,SQL等等都可以算作是外部DSL。外部DSL一般會直接針
9、對特定的領(lǐng)域設(shè)計,而不考慮其他方面。James Gosling曾經(jīng)說過:每個配置文件最終都會變成一門編程語言。一開始您可能只會用它表示一點點東西,慢慢地您便會想要一些規(guī)則,而這些規(guī)則則變成了表達式,后來您可能還會定義變量,進行條件判斷等等,而最終它就變成了一種奇怪的編程語言,這樣的情況屢見不鮮?,F(xiàn)在有一些公司也在關(guān)注DSL的開發(fā)。例如以前在微軟工作的Charles Simonyi提出了Intentional Programming的概念,還有JetBrains公司提供的一個叫做MPS(Meta Programming System)的產(chǎn)品。最近微軟也提出了自己的Oslo項目,而在Eclipse
10、世界里也有Xtext,所以其實如今在這方面也有不少人在嘗試。由于外部DSL的獨立性,在某些情況下也會出現(xiàn)特定的工具,輔助領(lǐng)域?qū)<一蚴情_發(fā)人員本身編寫DSL代碼。還有一些DSL會以XML方言的形式提出,利用XML方言的好處在于有不少現(xiàn)成的工具可用,這樣可以更快地定義自己的語法。而內(nèi)部DSL,正像之前提到的那樣,它往往只是代表了一系列特別的API及使用模式,例如LINQ查詢語句及Ruby on Rails中的Active Record聲明代碼等等。內(nèi)部DSL可以使用一系列API來“偽裝”成一種DSL,它往往會利用一些“流暢化”的技巧,例如像jQuery那樣把一些方法通過“點”連接起來,而另一些也會
11、利用元編程的方式。內(nèi)部DSL還有一些優(yōu)勢,例如可以訪問語言中的代碼或變量,以及利用代碼補全,重構(gòu)等母語言的所有特性。DSL的可讀性往往很高。例如,要篩選出單價大于20的產(chǎn)品,并對所屬種類進行分組,并降序地列出每組的分類名稱及產(chǎn)品數(shù)量。如果是用命令式的編程方式,則可能是這樣的:Dictionary<string, Grouping> groups = new Dictionary<string, Grouping>();foreach (Product p in products) if (p.UnitPrice >= 20) if (!groups.Contain
12、sKey(p.CategoryName) Grouping r = new Grouping(); r.CategoryName = p.CategoryName; r.ProductCount = 0; groupsp.CategoryName = r; groupsp.CategoryName.ProductCount+; List<Grouping> result = new List<Grouping>(groups.Values);result.Sort(delegate(Grouping x, Grouping y) return x.ProductCoun
13、t > y.ProductCount ? -1 : x.ProductCount < y.ProductCount ? 1 : 0;);顯然這些代碼編寫起來需要一點時間,且很難直接看出它的真實目的,換言之“What”幾乎完全被“How”所代替了。這樣,一個新的程序員必須花費一定時間才能理解這段代碼的目的。但如果使用LINQ,代碼便可以改寫成:var result = products .Where(p => p.UnitPrice >= 20) .GroupBy(p => p.CategoryName) .OrderByDescending(g => g.C
14、ount() .Select(g => new CategoryName = g.Key, ProductCount = g.Count() );這段代碼更加關(guān)注的是“What”而不是“How”,它不會明確地給出過濾的“操作方式”,也沒有涉及到創(chuàng)建字典這樣的細節(jié)。這段代碼還可以利用C# 3.0中內(nèi)置的DSL,即LINQ查詢語句來改寫:var result = from p in products where p.UnitPrice >= 20 group p by p.CategoryName into g orderby g.Count() descending select n
15、ew CategoryName = g.Key, ProductCount = g.Count() ;編譯器會簡單地將LINQ差距語句轉(zhuǎn)化為前一種形式。這段代碼只是表現(xiàn)出最終的目的,而不是明確指定做事的方式,這樣便可以很容易地并行執(zhí)行這段代碼,如使用PINQ則幾乎不需要做出任何修改。函數(shù)式編程Anders提出的另一個重要的聲明式編程方式便是函數(shù)式編程。函數(shù)式編程歷史悠久,它幾乎和編程語言本身同時誕生,如當年的LISP便是個函數(shù)式編程語言。除了LISP以外還有其他許多函數(shù)式編程語言,如APL、Haskell、ML等等。關(guān)于函數(shù)式編程在學(xué)術(shù)界已經(jīng)有過許多研究了,大約在5到10年前許多人開始吸收和整
16、理這些研究內(nèi)容,想要把它們?nèi)谌敫鼮橥ㄓ玫木幊陶Z言?,F(xiàn)在的編程語言,如C#、Python、Ruby、Scala等等,它們都受到了函數(shù)式編程語言的影響。使用命令式編程語言寫程序時,我們經(jīng)常會編寫如x = x + 1這樣的語句,此時我們大量依賴的是可變狀態(tài),或者說是“變量”,它們的值可以隨程序運行而改變??勺儬顟B(tài)非常強大,但隨之而來的便是被稱為“副作用”的問題,例如一個無需參數(shù)的void方法,它會根據(jù)調(diào)用次數(shù)或是在哪個線程上進行調(diào)用對程序產(chǎn)生影響,它會改變程序內(nèi)部的狀態(tài),從而影響之后的運行效果。而在函數(shù)式編程中則不會出現(xiàn)這個情況,因為所有的狀態(tài)都是不可變的。事實上對函數(shù)式編程的討論更像是數(shù)學(xué)、公式,
17、而不是程序語句,如x = x + 1對于數(shù)學(xué)家來說,似乎只是個永不為真的表達式而已。函數(shù)式編程十分容易并行,因為它在運行時不會修改任何狀態(tài),因此無論多少線程在運行時都可以觀察到正確的結(jié)果。假如兩個函數(shù)完全無關(guān),那么它們是并行還是順序地執(zhí)行便沒有什么區(qū)別了。當然,現(xiàn)實中的程序一定是有副作用的,例如向屏幕輸出內(nèi)容,向Socket傳輸數(shù)據(jù)等等,因此真實世界中的函數(shù)式編程往往都會考慮如何將有副作用的代碼分離出來。函數(shù)式編程默認是不可變的,開發(fā)人員必須做些額外的事情才能使用可變狀態(tài)或是危險的副作用,與之相反,如C#或Java必須使用readonly或是final來做到這一點。此時,使用函數(shù)式編程語言時的
18、思維觀念便會有所不同了。F#是微軟隨VS 2010推出的一門函數(shù)式編程語言,它基于OCaml的核心部分,因此是一門強類型編程語言,并支持一些如模式匹配,類型推斷等現(xiàn)代函數(shù)式編程語言的特性。在此之上,F(xiàn)#又增加了異步工作流,度量單位等較為前沿的語言功能。在F#中如果要計算一個列表所有元素之和,也可以使用命令式的風格來編寫代碼:let sumSquaresI l = let mutable acc = 0 for x in l do acc <- acc + sqr x acc只不過,F(xiàn)#中的一切默認都是不可變的,開發(fā)人員需要使用mutable關(guān)鍵字來聲明一個可變的狀態(tài)。事實上,在F#中更典
19、型做法是:let rec sumSquaresF l = match l with | -> 0 | head : tail -> sqr head + sumSquaresF tail在數(shù)學(xué)里我們經(jīng)常使用遞歸,把一個公式分解成幾個變化的形式,以此進行遞歸的定義。純函數(shù)式的代碼其“數(shù)學(xué)性”較強,如果您分析上面這段代碼,會發(fā)現(xiàn)它幾乎就是標準的數(shù)學(xué)定義。在編程時我們也使用遞歸的做法,編譯器會設(shè)法幫我們轉(zhuǎn)化成尾調(diào)用或是循環(huán)語句。動態(tài)語言與元編程動態(tài)語言不會嚴格區(qū)分“編譯時”和“運行時”。對于一些靜態(tài)編程語言(如C#),往往是先進行編譯,此時可能會得到一些編譯期錯誤,而對于動態(tài)語言來說這兩
20、個階段便混合在一起了。常見的動態(tài)語言有JavaScript,Python,Ruby,LISP等等。動態(tài)語言和靜態(tài)語言各有一些優(yōu)勢,這也是兩個陣營爭論多年的內(nèi)容。不過Anders認為它們各自都有十分重要的優(yōu)點,而未來不屬于其中任何一方。他表示,從編程語言發(fā)展過程中可以觀察到兩種特點正在合并的趨勢,未來應(yīng)該屬于兩者的雜交產(chǎn)物。許多人認定動態(tài)語言執(zhí)行起來很慢,也沒有類型安全等等。例如有這樣一段代碼:var a = 0, n = 10;for (var i = 0; i < n; i+) a += i;這段代碼在C#和JavaScript中都是合法的,但是它們的處理方式大相徑庭。在C#中,編譯器
21、可以推斷出a和n都是32位整數(shù),則for循環(huán)和相加操作都只是簡單的CPU指令,自然效率很高。但是對于JavaScript等動態(tài)類型語言來說,var只代表了“一個值”,它可以是任意類型,因此這里其實還會包含一個“類型標記”,表明它在運行時是什么類型的對象。所以兩者的區(qū)別之一便是,表示同樣的值在動態(tài)語言中會有一些額外的開銷,在如今的CPU中,“空間”也意味著“速度”,所以較大的值便需要較長時間進行處理,這里便損失了一部分效率。此外JavaScript在計算a加i時,那么必須先查看兩個變量中的類型標記,根據(jù)類型選擇出合適的相加操作,然后加載兩個值,最后再進行加法操作,一旦越界了還要利用double。
22、很明顯在這里也會帶來許多開銷。一般來說,動態(tài)語言是使用解釋器來執(zhí)行的,因此還有一些解釋器需要的二進制碼,把這些性能損失全部加起來以后,便會發(fā)現(xiàn)執(zhí)行代碼時需要10倍到100倍的性能開銷。不過近幾年出現(xiàn)的一些動態(tài)虛擬機或引擎將此類情況改善了許多。如今大部分的JavaScript引擎使用了JIT編譯器,于是便省下了解釋器的開銷,這樣性能損失便會減小至3到10倍。而在過去的兩三年間,JIT編譯器也變得越來越高效,瀏覽器中新一代的適應(yīng)性JIT編譯器,如TraceMonkey,V8,還有微軟在IE 9中使用的Chakra引擎。這種適應(yīng)性的JIT編譯器使用了一部分有趣的技術(shù),如Inline Caching、
23、Type Specialization、Hidden Classes、Tracing等等,它們可以將開銷降低至2到3倍的范圍內(nèi),這種效率的提升可謂十分神奇。在Anders看來,JavaScript引擎可能已經(jīng)接近了性能優(yōu)化的極限,我們在效率上可以提升的空間已經(jīng)不多。不過他同樣認為,如今JavaScript語言的性能已經(jīng)足夠快了,完全有能力作為Web客戶端的統(tǒng)治性語言。動態(tài)語言的關(guān)鍵之一便是“元編程”,“元編程”實際上是“代碼生成”的一種別稱,在日常應(yīng)用中開發(fā)人員其實經(jīng)常依賴這種做法了。在某些場景下使用動態(tài)語言會比靜態(tài)語言更加自然一些。例如在C#或Java里使用ORM時,一種傳統(tǒng)做法是讓代碼生成
24、器去觀察數(shù)據(jù)庫,并生成一大堆代碼,然后再編譯。而動態(tài)語言并沒有編譯期和執(zhí)行期的區(qū)別,例如在Ruby on Rails中使用ActiveRecord便無須定義各式字段。Anders談到,他和他的團隊也在努力改進靜態(tài)語言的元編程能力,如他們正在實現(xiàn)的“編譯器即服務(wù)(Compiler as a Service)”。傳統(tǒng)的編譯器是一個黑盒,一端輸入代碼,而另一端便會生成.NET程序集等數(shù)據(jù),開發(fā)人員很難參與或理解它的工作。但是在很多時候,開發(fā)人員并不一定需要編譯器來生成程序集,他們需要的是一些樹狀的表現(xiàn)形式,然后對它進行識別和重寫。因此,開發(fā)人員可能會越來越需要一些開放編譯器功能的API。這么做可以讓
25、靜態(tài)類型語言獲得許多有用的功能,包括元編程以及可操作的完整對象模型等等。并發(fā)Anders看來,多核革命的一個有趣之處在于,它會要求并發(fā)的思維方式有所改變。傳統(tǒng)的并發(fā)思維,是在單個CPU上執(zhí)行多個邏輯任務(wù),使用舊有的分時方式或是時間片模型來執(zhí)行多個任務(wù)。但是如今的并發(fā)場景則正好相反,是要將一個邏輯上的任務(wù)放在多個CPU上執(zhí)行。這改變了我們編寫程序的方式,這意味著對于語言或是API來說,我們需要有辦法來分解任務(wù),把它拆分成多個小任務(wù)后獨立的執(zhí)行,而傳統(tǒng)的編程語言中并不關(guān)注這點。使用目前的并發(fā)API來完成工作并不容易,比如Thread,ThreadPool,Monitor等等,開發(fā)人員很難走的太遠。不過在.NET 4.0中提供了一套強大的框架,即.NET并行擴展(Parallel Extensions),這是一種現(xiàn)代的并發(fā)模型,將邏輯上的任務(wù)并發(fā)與實際使用的的物理模型分離開來。以前的API都是直接處理線程等基礎(chǔ)元素,不過利用.NET并行擴展中的任務(wù)并行庫(Task Parallel Library),并行LINQ(Parallel LINQ)以及協(xié)調(diào)數(shù)據(jù)結(jié)構(gòu)(Coordination Data Structures)讓開發(fā)人員可以直接關(guān)注邏輯
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2022幼兒園元旦活動總結(jié)范文5篇
- 2022年建筑施工工作總結(jié)三篇
- 豫滿全球電商培訓(xùn)
- 石河子大學(xué)《足球》2022-2023學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《食品工藝學(xué)實驗》2022-2023學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《心理測量學(xué)》2022-2023學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《家畜環(huán)境衛(wèi)生學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《法律文書》2023-2024學(xué)年期末試卷
- 沈陽理工大學(xué)《商務(wù)俄語翻譯》2023-2024學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《建筑設(shè)計》2021-2022學(xué)年第一學(xué)期期末試卷
- 農(nóng)村夜校班國語試卷完整版
- 外國新聞傳播史 課件 第十八章 埃及的新聞傳播事業(yè)
- 四川航空介紹
- 從銷售到營銷的轉(zhuǎn)變與發(fā)展
- 機關(guān)食堂食品安全
- 氨氮的測定講解
- adidas阿迪達斯簡介
- 表 3.0.12-4 單位(子單位)工程質(zhì)量竣工驗收記錄
- 新能源汽車技術(shù)職業(yè)生涯規(guī)劃
- 新版查對制度專項檢查表(涵蓋患者身份識別、臨床診療行為、設(shè)備設(shè)施運行和醫(yī)療環(huán)境安全等相關(guān)方面)
- 企業(yè)法律合規(guī)與糾紛解決策略課件
評論
0/150
提交評論