一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

編程語(yǔ)言的發(fā)展趨勢(shì)及未來(lái)方向

  這是一篇發(fā)表在《程序員》雜志8月刊的文章,是根據(jù)我對(duì)Anders Hejlsberg的演講內(nèi)容的翻譯的縮寫。原本的完整演講內(nèi)容有數(shù)萬(wàn)字,為了在雜志上發(fā)表因此簡(jiǎn)化成了五千字,因此如果您對(duì)完整內(nèi)容感興趣,不妨根據(jù)文末鏈接來(lái)訪問(wèn)完整內(nèi)容,其中也包含大量分解的幻燈片以及代碼。

  概述

  程序設(shè)計(jì)離不開(kāi)編程語(yǔ)言,但是編程語(yǔ)言在國(guó)內(nèi)的大環(huán)境中似乎一直是個(gè)二等公民。國(guó)內(nèi)的計(jì)算機(jī)教育和工程培訓(xùn),似乎一直在宣傳“語(yǔ)言不重要,重要的是思想”,“語(yǔ)言一通百通”等觀點(diǎn),甚至在許多人眼中“語(yǔ)言的討論”完全是不入流的,但其實(shí)“編程語(yǔ)言”與“工具”、“框架”或是“開(kāi)發(fā)方法”等事物一樣,都對(duì)生產(chǎn)力有著重要的影響。事實(shí)上,語(yǔ)言的發(fā)展歷史比其他方面更為悠久,并且在過(guò)去十幾年,甚至最近幾年中都依然在不斷的碰撞,演變。期間一些新的語(yǔ)言誕生了,而另一些在當(dāng)時(shí)看來(lái)陽(yáng)春白雪的語(yǔ)言和編程范式也重新獲得了人們的重視。

  Anders Hejlsberg是微軟的Technical Fellow,擔(dān)任C#編程語(yǔ)言的首席架構(gòu)師,也參與了.NET Framework,以及VB.NET和F#等語(yǔ)言的設(shè)計(jì)與開(kāi)發(fā)。幾個(gè)月前,Anders在比利時(shí)的TechDays 2010荷蘭DevDays 2010分別進(jìn)行了一場(chǎng)演講,闡述了他眼中對(duì)于編程語(yǔ)言的發(fā)展趨勢(shì)及未來(lái)方向,本文便對(duì)他的觀點(diǎn)進(jìn)行了總結(jié)。

  大約25到30年前,Anders開(kāi)發(fā)了著名的Turbo Pascal,這是一套集語(yǔ)言、編譯器及開(kāi)發(fā)工具于一體的產(chǎn)品,這也是Anders進(jìn)入編程語(yǔ)言這一領(lǐng)域的起點(diǎn)。Anders談到,如今的計(jì)算機(jī)和當(dāng)年他開(kāi)發(fā)的Turbo Pascal所用的Z-80已經(jīng)不可同日而語(yǔ)。從那時(shí)算起,如今的機(jī)器已經(jīng)有大約10萬(wàn)倍的外部存儲(chǔ)容量,1萬(wàn)倍的內(nèi)存大小,CPU速度也有大約1000倍的提高。但是,如果我們比較如今的Java代碼及當(dāng)年P(guān)ascal代碼,會(huì)發(fā)現(xiàn)它們的差別其實(shí)并不大。Anders認(rèn)為編程語(yǔ)言的發(fā)展非常緩慢,期間當(dāng)然出現(xiàn)了一些東西,例如面向?qū)ο蟮鹊龋沁h(yuǎn)沒(méi)有好上1000倍。事實(shí)上,近幾十年來(lái)的努力主要體現(xiàn)在框架及工具等方面(如下圖)。例如.NET Framework里有超過(guò)一萬(wàn)個(gè)類及十萬(wàn)個(gè)方法,與Turbo Pascal相比的確有了超過(guò)1000倍的增長(zhǎng)。同樣類似,現(xiàn)在的IDE包含了無(wú)數(shù)強(qiáng)大的功能,例如語(yǔ)法提示,重構(gòu),調(diào)試器等等。與此相比,編程語(yǔ)言的改進(jìn)的確很不明顯。

  在過(guò)去5、60年的編程歷史中,編程語(yǔ)言的抽象級(jí)別不斷提高,人們都在努力讓編程語(yǔ)言更有表現(xiàn)力,這樣我們可以用更少的代碼完成更多的工作。我們一開(kāi)始使用匯編,然后使用面向過(guò)程的語(yǔ)言(如Pascal和C),然后是面向?qū)ο笳Z(yǔ)言(如C++),隨后便進(jìn)入了托管時(shí)代,語(yǔ)言運(yùn)行于受托管的執(zhí)行環(huán)境上(如C#,Java),它們的主要特性有自動(dòng)的垃圾收集,類型安全等等。Anders認(rèn)為這樣的趨勢(shì)還會(huì)繼續(xù)保持下去,我們還會(huì)看到抽象級(jí)別越來(lái)越高的語(yǔ)言,而語(yǔ)言的設(shè)計(jì)者則必須理解并預(yù)測(cè)下一個(gè)抽象級(jí)別是什么樣子的。另一方面,如.NET,Java等框架的重要性提高了許多,編程語(yǔ)言往往都傾向于構(gòu)建于現(xiàn)有的工具上,而不會(huì)從頭寫起?,F(xiàn)在出現(xiàn)的編程語(yǔ)言,例如F#,以及Java領(lǐng)域的ScalaClojure等等,它們都是基于現(xiàn)有框架構(gòu)建的,每次從頭開(kāi)始的代價(jià)實(shí)在太高。

  在Anders眼中,如今影響力較大的趨勢(shì)主要有三種(如下圖),它們分別是“聲明式的編程風(fēng)格”(包括“領(lǐng)域特定語(yǔ)言”及“函數(shù)式編程”)、過(guò)去的五年非常火熱的“動(dòng)態(tài)語(yǔ)言”(其最重要的方面便是“元編程”能力)以及多核環(huán)境下的“并發(fā)編程。此外隨著語(yǔ)言的發(fā)展,原本常用的“面向?qū)ο?rdquo;語(yǔ)言,“動(dòng)態(tài)語(yǔ)言”或是“函數(shù)式”等邊界也變得越來(lái)越模糊,例如各種主要的編程語(yǔ)言都受到函數(shù)式語(yǔ)言的影響。因此,“多范式”程序設(shè)計(jì)語(yǔ)言也是一個(gè)愈發(fā)明顯的趨勢(shì)。

  聲明式編程與DSL

  目前常見(jiàn)的編程語(yǔ)言大都是命令式(Imperative)的,例如C#,Java或是C++等等。這些語(yǔ)言的特征在于,代碼里不僅表現(xiàn)了“做什么(What)”,而更多表現(xiàn)出“如何(How)完成工作”這樣的實(shí)現(xiàn)細(xì)節(jié),例如for循環(huán),i += 1等等,甚至這部分細(xì)節(jié)會(huì)掩蓋了我們的“最終目標(biāo)”。在Anders看來(lái),命令式編程通常會(huì)讓代碼變得十分冗余,更重要的是由于它提供了過(guò)于具體的指令,這樣執(zhí)行代碼的基礎(chǔ)設(shè)施(如CLR或JVM)沒(méi)有太多發(fā)揮空間,只能老老實(shí)實(shí)地根據(jù)指令一步步的向目標(biāo)前進(jìn)。例如,并行執(zhí)行程序會(huì)變得十分困難,因?yàn)橄?ldquo;執(zhí)行目的”這樣更高層次的信息已經(jīng)丟失了。因此,編程語(yǔ)言的趨勢(shì)之一,便是能讓代碼包含更多的“What”,而不是“How”,這樣執(zhí)行環(huán)境便可以更加聰明地去適應(yīng)當(dāng)前的執(zhí)行要求。

  關(guān)于聲明式的編程風(fēng)格,Anders主要提出了兩個(gè)方面,第一個(gè)方面是DSL(Domain Specific Language,領(lǐng)域特定語(yǔ)言)。DSL不是什么新鮮的玩意兒,我們平時(shí)經(jīng)常接觸的SQL,CSS,正則表達(dá)式等等都屬于DSL。有的DSL可能更加專注于一個(gè)方面,例如Mathematica,LOGO等等。這些語(yǔ)言的目標(biāo)都是特定的領(lǐng)域,與之相對(duì)的則是GPPL(General Purpose Programming Language,通用目的編程語(yǔ)言)。Martin Fowler將DSL分為外部DSL及內(nèi)部DSL兩種。外部DSL有自己的特定語(yǔ)法、解析器和詞法分析器等等,它們往往是一種小型的編程語(yǔ)言,甚至不會(huì)像GPPL那樣需要源文件。與之相對(duì)的則是內(nèi)部DSL。內(nèi)部DSL其實(shí)更像是種別稱,它代表一類特別API及使用模式。

  XSLT,SQL等等都可以算作是外部DSL。外部DSL一般會(huì)直接針對(duì)特定的領(lǐng)域設(shè)計(jì),而不考慮其他方面。James Gosling曾經(jīng)說(shuō)過(guò):每個(gè)配置文件最終都會(huì)變成一門編程語(yǔ)言。一開(kāi)始您可能只會(huì)用它表示一點(diǎn)點(diǎn)東西,慢慢地您便會(huì)想要一些規(guī)則,而這些規(guī)則則變成了表達(dá)式,后來(lái)您可能還會(huì)定義變量,進(jìn)行條件判斷等等,而最終它就變成了一種奇怪的編程語(yǔ)言,這樣的情況屢見(jiàn)不鮮?,F(xiàn)在有一些公司也在關(guān)注DSL的開(kāi)發(fā)。例如以前在微軟工作的Charles Simonyi提出了Intentional Programming的概念,還有JetBrains公司提供的一個(gè)叫做MPS(Meta Programming System)的產(chǎn)品。最近微軟也提出了自己的Oslo項(xiàng)目,而在Eclipse世界里也有Xtext,所以其實(shí)如今在這方面也有不少人在嘗試。由于外部DSL的獨(dú)立性,在某些情況下也會(huì)出現(xiàn)特定的工具,輔助領(lǐng)域?qū)<一蚴情_(kāi)發(fā)人員本身編寫DSL代碼。還有一些DSL會(huì)以XML方言的形式提出,利用XML方言的好處在于有不少現(xiàn)成的工具可用,這樣可以更快地定義自己的語(yǔ)法。

  而內(nèi)部DSL,正像之前提到的那樣,它往往只是代表了一系列特別的API及使用模式,例如LINQ查詢語(yǔ)句及Ruby on Rails中的Active Record聲明代碼等等。內(nèi)部DSL可以使用一系列API來(lái)“偽裝”成一種DSL,它往往會(huì)利用一些“流暢化”的技巧,例如像jQuery那樣把一些方法通過(guò)“點(diǎn)”連接起來(lái),而另一些也會(huì)利用元編程的方式。內(nèi)部DSL還有一些優(yōu)勢(shì),例如可以訪問(wèn)語(yǔ)言中的代碼或變量,以及利用代碼補(bǔ)全,重構(gòu)等母語(yǔ)言的所有特性。

  DSL的可讀性往往很高。例如,要篩選出單價(jià)大于20的產(chǎn)品,并對(duì)所屬種類進(jìn)行分組,并降序地列出每組的分類名稱及產(chǎn)品數(shù)量。如果是用命令式的編程方式,則可能是這樣的:

Dictionary<string, Grouping> groups = new Dictionary<string, Grouping>();
foreach (Product p in products)
{
if (p.UnitPrice >= 20)
{
if (!groups.ContainsKey(p.CategoryName))
{
Grouping r = new Grouping();
r.CategoryName = p.CategoryName;
r.ProductCount = 0;
groups[p.CategoryName] = r;
}
groups[p.CategoryName].ProductCount++;
}
}

List<Grouping> result = new List<Grouping>(groups.Values);
result.Sort(delegate(Grouping x, Grouping y)
{
return
x.ProductCount > y.ProductCount ? -1 :
x.ProductCount < y.ProductCount ? 1 :
0;
});

  顯然這些代碼編寫起來(lái)需要一點(diǎn)時(shí)間,且很難直接看出它的真實(shí)目的,換言之“What”幾乎完全被“How”所代替了。這樣,一個(gè)新的程序員必須花費(fèi)一定時(shí)間才能理解這段代碼的目的。但如果使用LINQ,代碼便可以改寫成:

var result = products
.Where(p => p.UnitPrice >= 20)
.GroupBy(p => p.CategoryName)
.OrderByDescending(g => g.Count())
.Select(g => new { CategoryName = g.Key, ProductCount = g.Count() });

  這段代碼更加關(guān)注的是“What”而不是“How”,它不會(huì)明確地給出過(guò)濾的“操作方式”,也沒(méi)有涉及到創(chuàng)建字典這樣的細(xì)節(jié)。這段代碼還可以利用C# 3.0中內(nèi)置的DSL,即LINQ查詢語(yǔ)句來(lái)改寫:

var result =
from p in products
where p.UnitPrice >= 20
group p by p.CategoryName into g
orderby g.Count() descending
select new
{ CategoryName = g.Key, ProductCount = g.Count() };

  編譯器會(huì)簡(jiǎn)單地將LINQ差距語(yǔ)句轉(zhuǎn)化為前一種形式。這段代碼只是表現(xiàn)出最終的目的,而不是明確指定做事的方式,這樣便可以很容易地并行執(zhí)行這段代碼,如使用PINQ則幾乎不需要做出任何修改。

  函數(shù)式編程

  Anders提出的另一個(gè)重要的聲明式編程方式便是函數(shù)式編程。函數(shù)式編程歷史悠久,它幾乎和編程語(yǔ)言本身同時(shí)誕生,如當(dāng)年的LISP便是個(gè)函數(shù)式編程語(yǔ)言。除了LISP以外還有其他許多函數(shù)式編程語(yǔ)言,如APLHaskell、ML等等。關(guān)于函數(shù)式編程在學(xué)術(shù)界已經(jīng)有過(guò)許多研究了,大約在5到10年前許多人開(kāi)始吸收和整理這些研究?jī)?nèi)容,想要把它們?nèi)谌敫鼮橥ㄓ玫木幊陶Z(yǔ)言?,F(xiàn)在的編程語(yǔ)言,如C#、Python、Ruby、Scala等等,它們都受到了函數(shù)式編程語(yǔ)言的影響。

  使用命令式編程語(yǔ)言寫程序時(shí),我們經(jīng)常會(huì)編寫如x = x + 1這樣的語(yǔ)句,此時(shí)我們大量依賴的是可變狀態(tài),或者說(shuō)是“變量”,它們的值可以隨程序運(yùn)行而改變??勺儬顟B(tài)非常強(qiáng)大,但隨之而來(lái)的便是被稱為“副作用”的問(wèn)題,例如一個(gè)無(wú)需參數(shù)的void方法,它會(huì)根據(jù)調(diào)用次數(shù)或是在哪個(gè)線程上進(jìn)行調(diào)用對(duì)程序產(chǎn)生影響,它會(huì)改變程序內(nèi)部的狀態(tài),從而影響之后的運(yùn)行效果。而在函數(shù)式編程中則不會(huì)出現(xiàn)這個(gè)情況,因?yàn)樗械臓顟B(tài)都是不可變的。事實(shí)上對(duì)函數(shù)式編程的討論更像是數(shù)學(xué)、公式,而不是程序語(yǔ)句,如x = x + 1對(duì)于數(shù)學(xué)家來(lái)說(shuō),似乎只是個(gè)永不為真的表達(dá)式而已。

  函數(shù)式編程十分容易并行,因?yàn)樗谶\(yùn)行時(shí)不會(huì)修改任何狀態(tài),因此無(wú)論多少線程在運(yùn)行時(shí)都可以觀察到正確的結(jié)果。假如兩個(gè)函數(shù)完全無(wú)關(guān),那么它們是并行還是順序地執(zhí)行便沒(méi)有什么區(qū)別了。當(dāng)然,現(xiàn)實(shí)中的程序一定是有副作用的,例如向屏幕輸出內(nèi)容,向Socket傳輸數(shù)據(jù)等等,因此真實(shí)世界中的函數(shù)式編程往往都會(huì)考慮如何將有副作用的代碼分離出來(lái)。函數(shù)式編程默認(rèn)是不可變的,開(kāi)發(fā)人員必須做些額外的事情才能使用可變狀態(tài)或是危險(xiǎn)的副作用,與之相反,如C#或Java必須使用readonly或是final來(lái)做到這一點(diǎn)。此時(shí),使用函數(shù)式編程語(yǔ)言時(shí)的思維觀念便會(huì)有所不同了。

  F#是微軟隨VS 2010推出的一門函數(shù)式編程語(yǔ)言,它基于OCaml的核心部分,因此是一門強(qiáng)類型編程語(yǔ)言,并支持一些如模式匹配,類型推斷等現(xiàn)代函數(shù)式編程語(yǔ)言的特性。在此之上,F(xiàn)#又增加了異步工作流,度量單位等較為前沿的語(yǔ)言功能。在F#中如果要計(jì)算一個(gè)列表所有元素之和,也可以使用命令式的風(fēng)格來(lái)編寫代碼:

let sumSquaresI l = 
let mutable acc = 0
for x in l do
acc <- acc + sqr x
acc

  只不過(guò),F(xiàn)#中的一切默認(rèn)都是不可變的,開(kāi)發(fā)人員需要使用mutable關(guān)鍵字來(lái)聲明一個(gè)可變的狀態(tài)。事實(shí)上,在F#中更典型做法是:

let rec sumSquaresF l = 
match l with
| [] -> 0
| head :: tail -> sqr head + sumSquaresF tail

  在數(shù)學(xué)里我們經(jīng)常使用遞歸,把一個(gè)公式分解成幾個(gè)變化的形式,以此進(jìn)行遞歸的定義。純函數(shù)式的代碼其“數(shù)學(xué)性”較強(qiáng),如果您分析上面這段代碼,會(huì)發(fā)現(xiàn)它幾乎就是標(biāo)準(zhǔn)的數(shù)學(xué)定義。在編程時(shí)我們也使用遞歸的做法,編譯器會(huì)設(shè)法幫我們轉(zhuǎn)化成尾調(diào)用或是循環(huán)語(yǔ)句。

  動(dòng)態(tài)語(yǔ)言與元編程

  動(dòng)態(tài)語(yǔ)言不會(huì)嚴(yán)格區(qū)分“編譯時(shí)”和“運(yùn)行時(shí)”。對(duì)于一些靜態(tài)編程語(yǔ)言(如C#),往往是先進(jìn)行編譯,此時(shí)可能會(huì)得到一些編譯期錯(cuò)誤,而對(duì)于動(dòng)態(tài)語(yǔ)言來(lái)說(shuō)這兩個(gè)階段便混合在一起了。常見(jiàn)的動(dòng)態(tài)語(yǔ)言有JavaScript,Python,Ruby,LISP等等。動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言各有一些優(yōu)勢(shì),這也是兩個(gè)陣營(yíng)爭(zhēng)論多年的內(nèi)容。不過(guò)Anders認(rèn)為它們各自都有十分重要的優(yōu)點(diǎn),而未來(lái)不屬于其中任何一方。他表示,從編程語(yǔ)言發(fā)展過(guò)程中可以觀察到兩種特點(diǎn)正在合并的趨勢(shì),未來(lái)應(yīng)該屬于兩者的雜交產(chǎn)物。

  許多人認(rèn)定動(dòng)態(tài)語(yǔ)言執(zhí)行起來(lái)很慢,也沒(méi)有類型安全等等。例如有這樣一段代碼:

var a = 0, n = 10;
for (var i = 0; i < n; i++) {
a += i;
}

  這段代碼在C#和JavaScript中都是合法的,但是它們的處理方式大相徑庭。在C#中,編譯器可以推斷出a和n都是32位整數(shù),則for循環(huán)和相加操作都只是簡(jiǎn)單的CPU指令,自然效率很高。但是對(duì)于JavaScript等動(dòng)態(tài)類型語(yǔ)言來(lái)說(shuō),var只代表了“一個(gè)值”,它可以是任意類型,因此這里其實(shí)還會(huì)包含一個(gè)“類型標(biāo)記”,表明它在運(yùn)行時(shí)是什么類型的對(duì)象。所以兩者的區(qū)別之一便是,表示同樣的值在動(dòng)態(tài)語(yǔ)言中會(huì)有一些額外的開(kāi)銷,在如今的CPU中,“空間”也意味著“速度”,所以較大的值便需要較長(zhǎng)時(shí)間進(jìn)行處理,這里便損失了一部分效率。此外JavaScript在計(jì)算a加i時(shí),那么必須先查看兩個(gè)變量中的類型標(biāo)記,根據(jù)類型選擇出合適的相加操作,然后加載兩個(gè)值,最后再進(jìn)行加法操作,一旦越界了還要利用double。很明顯在這里也會(huì)帶來(lái)許多開(kāi)銷。一般來(lái)說(shuō),動(dòng)態(tài)語(yǔ)言是使用解釋器來(lái)執(zhí)行的,因此還有一些解釋器需要的二進(jìn)制碼,把這些性能損失全部加起來(lái)以后,便會(huì)發(fā)現(xiàn)執(zhí)行代碼時(shí)需要10倍到100倍的性能開(kāi)銷。

  不過(guò)近幾年出現(xiàn)的一些動(dòng)態(tài)虛擬機(jī)或引擎將此類情況改善了許多。如今大部分的JavaScript引擎使用了JIT編譯器,于是便省下了解釋器的開(kāi)銷,這樣性能損失便會(huì)減小至3到10倍。而在過(guò)去的兩三年間,JIT編譯器也變得越來(lái)越高效,瀏覽器中新一代的適應(yīng)性JIT編譯器,如TraceMonkeyV8,還有微軟在IE 9中使用的Chakra引擎。這種適應(yīng)性的JIT編譯器使用了一部分有趣的技術(shù),如Inline Caching、Type Specialization、Hidden Classes、Tracing等等,它們可以將開(kāi)銷降低至2到3倍的范圍內(nèi),這種效率的提升可謂十分神奇。在Anders看來(lái),JavaScript引擎可能已經(jīng)接近了性能優(yōu)化的極限,我們?cè)谛噬峡梢蕴嵘目臻g已經(jīng)不多。不過(guò)他同樣認(rèn)為,如今JavaScript語(yǔ)言的性能已經(jīng)足夠快了,完全有能力作為Web客戶端的統(tǒng)治性語(yǔ)言。

  動(dòng)態(tài)語(yǔ)言的關(guān)鍵之一便是“元編程”,“元編程”實(shí)際上是“代碼生成”的一種別稱,在日常應(yīng)用中開(kāi)發(fā)人員其實(shí)經(jīng)常依賴這種做法了。在某些場(chǎng)景下使用動(dòng)態(tài)語(yǔ)言會(huì)比靜態(tài)語(yǔ)言更加自然一些。例如在C#或Java里使用ORM時(shí),一種傳統(tǒng)做法是讓代碼生成器去觀察數(shù)據(jù)庫(kù),并生成一大堆代碼,然后再編譯。而動(dòng)態(tài)語(yǔ)言并沒(méi)有編譯期和執(zhí)行期的區(qū)別,例如在Ruby on Rails中使用ActiveRecord便無(wú)須定義各式字段。

  Anders談到,他和他的團(tuán)隊(duì)也在努力改進(jìn)靜態(tài)語(yǔ)言的元編程能力,如他們正在實(shí)現(xiàn)的“編譯器即服務(wù)(Compiler as a Service)”。傳統(tǒng)的編譯器是一個(gè)黑盒,一端輸入代碼,而另一端便會(huì)生成.NET程序集等數(shù)據(jù),開(kāi)發(fā)人員很難參與或理解它的工作。但是在很多時(shí)候,開(kāi)發(fā)人員并不一定需要編譯器來(lái)生成程序集,他們需要的是一些樹(shù)狀的表現(xiàn)形式,然后對(duì)它進(jìn)行識(shí)別和重寫。因此,開(kāi)發(fā)人員可能會(huì)越來(lái)越需要一些開(kāi)放編譯器功能的API。這么做可以讓靜態(tài)類型語(yǔ)言獲得許多有用的功能,包括元編程以及可操作的完整對(duì)象模型等等。

  并發(fā)

  Anders看來(lái),多核革命的一個(gè)有趣之處在于,它會(huì)要求并發(fā)的思維方式有所改變。傳統(tǒng)的并發(fā)思維,是在單個(gè)CPU上執(zhí)行多個(gè)邏輯任務(wù),使用舊有的分時(shí)方式或是時(shí)間片模型來(lái)執(zhí)行多個(gè)任務(wù)。但是如今的并發(fā)場(chǎng)景則正好相反,是要將一個(gè)邏輯上的任務(wù)放在多個(gè)CPU上執(zhí)行。這改變了我們編寫程序的方式,這意味著對(duì)于語(yǔ)言或是API來(lái)說(shuō),我們需要有辦法來(lái)分解任務(wù),把它拆分成多個(gè)小任務(wù)后獨(dú)立的執(zhí)行,而傳統(tǒng)的編程語(yǔ)言中并不關(guān)注這點(diǎn)。

  使用目前的并發(fā)API來(lái)完成工作并不容易,比如Thread,ThreadPool,Monitor等等,開(kāi)發(fā)人員很難走的太遠(yuǎn)。不過(guò)在.NET 4.0中提供了一套強(qiáng)大的框架,即.NET并行擴(kuò)展(Parallel Extensions),這是一種現(xiàn)代的并發(fā)模型,將邏輯上的任務(wù)并發(fā)與實(shí)際使用的的物理模型分離開(kāi)來(lái)。以前的API都是直接處理線程等基礎(chǔ)元素,不過(guò)利用.NET并行擴(kuò)展中的任務(wù)并行庫(kù)(Task Parallel Library),并行LINQ(Parallel LINQ)以及協(xié)調(diào)數(shù)據(jù)結(jié)構(gòu)(Coordination Data Structures)讓開(kāi)發(fā)人員可以直接關(guān)注邏輯上的任務(wù),而不必關(guān)心它們是如何運(yùn)行的,或是使用了多少個(gè)線程和CPU等等。利用LINQ這樣的DSL也有助于寫出并行的代碼,如果使用普通的for循環(huán)配合線程池來(lái)實(shí)現(xiàn)并行,則開(kāi)發(fā)人員很容易在各種API里失去方向。

  不過(guò)事實(shí)上,編寫并行的代碼依然很困難,尤其是要識(shí)別出可以并行的地方。Anders認(rèn)為很多時(shí)候還是需要編程語(yǔ)言來(lái)關(guān)注這方面的事情(如下圖)。比如“隔離性(Isolation)”,即編譯器如何發(fā)現(xiàn)這段代碼是獨(dú)立的,便可以將其安全地并發(fā)執(zhí)行。某段代碼創(chuàng)建了一個(gè)對(duì)象,在分享給其他人之前,我們對(duì)它的改變是安全的,但是一旦將其共享出去以后便完全不同了。因此理想中的類型系統(tǒng)應(yīng)該可以跟蹤到這樣的共享,如Linear Types——這在學(xué)術(shù)界也有一些研究。編程語(yǔ)言也可以在函數(shù)的純潔性(Purity)方面下功夫,如關(guān)注某個(gè)函數(shù)是否有副作用,有些時(shí)候編譯器可以做這方面的檢查,它可以禁止某些操作,以此保證我們寫出無(wú)副作用的純函數(shù)。另外便是不可變性(Immutability),目前的語(yǔ)言,如C#或VB,我們需要額外的工作才能寫出不可變的代碼。Anders認(rèn)為合適的做法應(yīng)該是在語(yǔ)言層面上更好的支持不可變性。這些都是在并發(fā)方面需要考慮的問(wèn)題。

  Anders還提到了他在思考并發(fā)語(yǔ)言特性時(shí)所遵循的原則:一個(gè)語(yǔ)言特性不應(yīng)該針對(duì)某個(gè)特定的并發(fā)模型,而應(yīng)該是一種通用的,可用于各種不同的并發(fā)場(chǎng)景的特性,就像隔離性、純潔性及不可變性那樣。語(yǔ)言擁有這樣的特性之后,就可以用于構(gòu)建各種不同的API,各種并發(fā)方式都可以利用到核心的語(yǔ)言特性。

  總結(jié)

  Anders認(rèn)為,對(duì)于編程語(yǔ)言來(lái)說(shuō),現(xiàn)在出現(xiàn)了許多有趣的東西,也是個(gè)令人激動(dòng)的時(shí)刻。在過(guò)去,大約是1995到2005年,的確可以說(shuō)是一個(gè)編程語(yǔ)言的黃金時(shí)期。當(dāng)Java出現(xiàn)的時(shí)候,編程語(yǔ)言的門檻變得平坦了,一切都是Java,似乎其他編程語(yǔ)言都完蛋了,程序設(shè)計(jì)者也沒(méi)什么可做的。不過(guò)大家又逐漸發(fā)現(xiàn),其實(shí)這遠(yuǎn)沒(méi)有結(jié)束。現(xiàn)在回顧起來(lái),會(huì)發(fā)現(xiàn)這段時(shí)間又出現(xiàn)了許多有趣的編程語(yǔ)言,這其實(shí)也代表了我們?cè)诰幊填I(lǐng)域上的進(jìn)步。

  完整內(nèi)容

it知識(shí)庫(kù)編程語(yǔ)言的發(fā)展趨勢(shì)及未來(lái)方向,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 久久福利青草狠狠午夜 | 法国性xxxxx极品 | 亚洲一区二区三区中文字幕5566 | 狠狠色噜噜狠狠狠97影音先锋 | 色老板最新网址 | 国内精品久久久久久中文字幕 | 最新国产视频 | 国内精品福利在线视频 | 国产精品视频一区二区三区小说 | 在线青草| 日本欧美强乱视频在线 | 秋霞伊人网 | 性满足久久久久久久久 | 免费在线观看黄视频 | 中文字幕亚洲一区二区三区 | 亚洲美女视频网 | 美女三级网站 | 国产精品亚洲第一区焦香 | 九九色综合 | 久草久操| www日韩在线| 亚洲图片另类 | 成人精品视频网站 | 亚洲国产区 | 一本伊人 | 9797在线看片亚洲精品 | 特黄毛片 | 中文字幕亚洲图片 | 午夜视频福利在线 | 亚洲国产视频网站 | 国产综合变态自虐重口另类 | 中文字幕精品一区二区日本 | 色哟哟在线观看视频 | 91在线网站 | 在线观看视频一区二区 | 成人在线激情视频 | 亚洲免费网站 | 在线视频99| 麻豆精品 | 狠狠88综合久久久久综合网 | 最新国产福利在线观看 |