最近寫了一篇關(guān)于C++0x Concepts的文章,意料之外地引起了一場小規(guī)??谒?。回各位帖子的同時,回想這些年C++社群的大小爭論,覺得有必要把一些長久以來在C++爭論中出現(xiàn)的誤解列舉出來。
…History became legend, legend became myth …- The Lord of the Rings
哈雷將軍的笑話想必大家都聽過。一句話經(jīng)口口相傳,每個人都根據(jù)自己的主觀意念加以潤色,修補,歪曲…到最后就面目全非。這里最關(guān)鍵的一環(huán)就是主觀意
識,在歷史學(xué)里面有這么一句話,大致意思是歷史其實只存在于人的意念之中;就算完全客觀的事件,通過不同的人的嘴說出來,造成的心理效應(yīng)也往往不一樣,每
個人都會加上那么一兩個形容詞,駕馭語言能力高的更是能夠舌綻蓮花,而語言本就有自身的力量,其中的遣詞造句對讀者構(gòu)成的心理影響力便應(yīng)運而生。甚至于同
一句話,用不同的語氣說出來,都會造成不同的效果。同一句話,站在不同的立場上看,也會根本不是同一個意思。比如“C++還算是門不錯的語言”,站在C+
+擁護(hù)者的角度聽是在憐憫加詆毀C++,而站在C++反對者的角度聽卻是抬舉了C++。
在一個長期被廣泛爭論的話題中,幾乎無可避
免的總是存在一些Fallacies和Myths。比如動態(tài)&靜態(tài)類型系統(tǒng)的爭論,據(jù)說從圖靈時代就開始了,到現(xiàn)在還有各種各樣的誤解,而且,可
以說,時間越長,系統(tǒng)內(nèi)的Fallacy越多。就連異常(exception)這樣不算復(fù)雜的語言特性里面居然也有一些長期存在的誤解。
至于這些Fallacies和Myths出現(xiàn)的原因很多:有人要“內(nèi)涵”唬人、有人要維護(hù)自己的心理優(yōu)勢、有人要維護(hù)自己的政權(quán)、有人要維護(hù)自己的利
益、有人因為話從別人那里聽了半句轉(zhuǎn)述給別人聽的時候按主觀意念補全(誰愿意說“我不知道”呢?)、有人干脆就是人云亦云…
所以,一句話,在一個靠口頭表達(dá)交換信息的社會中,F(xiàn)allacies和Myths是無處不在的,因為從內(nèi)心真實想法到外界表現(xiàn)出來的想法之間存在著“口
頭表達(dá)”這一中間層,后者由主觀意志支配。這里的中間層可不比軟件工程里面的間接層,在這個間接層上惡魔可以變成天使,天使也可以變成惡魔;六月飛雪可以
變成天降祥瑞,瓢潑大雨也可以變成艷陽高照。Anyway,這展開來就是一個心理學(xué)的問題了,不多廢話了,有興趣的可以去看Harry G.
Frankfurt寫的《On Bullshit》或者Scott Berkun的這篇短文——“How to detect
bullshit”。呃…我說“一句話”了么?
C++ - Fallacies and Myths
C++作為一門被爭論不斷的語言,其中Fallacies和Myths自然不會少。一般來說,一個問題在被大眾爭論中交換的話語數(shù)量與其中的Fallacy數(shù)量成正比。但一般來說主要的Fallacies就那么幾個:
Fallacy #1 ——C++社群的哲學(xué)太學(xué)院派
讓我們先對“學(xué)院派”下一個定義好不好?先問你自己一個問題,你心目中對“學(xué)院派”的定義是什么? 以下是一些選項: 1. 傾向于理論美。2.
忽視實際編碼中的constraints(如效率,模塊性、可讀性等等)。3. 倡導(dǎo)語言律師行為。4. 鉆細(xì)節(jié)。5. …
我想如果我說C++語言設(shè)計強(qiáng)調(diào)理論美,所有學(xué)過C++的人恐怕都會笑了…正如Bjarne自己所說的,C++設(shè)計初期的Rule of
Thumb之一便是“不要陷入到對完美性的固執(zhí)追求中”;不過具有諷刺意味的是,后面你會看到,正是這樣的一種哲學(xué)帶來了今天對C++的這個誤解。
我猜持這樣一種觀點的人大多對于學(xué)院派的定義都是模糊的,一般都介于“提倡鉆語言細(xì)節(jié)并利用語言細(xì)節(jié)的做法”、“關(guān)注語言特性本身而忽略實際編碼需
求”、“對語言細(xì)節(jié)無休止的爭論”等等之間。
所以,當(dāng)有人說“C++==學(xué)院派”的時候,他的真實意思很可能是:“C++語言的陰暗角落太多,而且C++社群還有提倡對語言角落把握的潛在哲學(xué),就連
C++0x的進(jìn)化也似乎更多關(guān)注語言特性,而那些語言特性根本就跟我們實際開發(fā)者脫節(jié)了…”等等。
首先得承認(rèn)的是,在近一個十年的時間內(nèi),C++社群的確某種程度上建立起了一種對語言細(xì)節(jié)過分關(guān)注的心態(tài),這種心態(tài)毫無疑問是錯誤的,但只有知道這個錯誤
是如何來的,才能解開這個結(jié)。而且,就算一時解不開這個結(jié),知道了原因之后才能保持理性的寬容態(tài)度,而不是亂發(fā)抱怨。一個理性的態(tài)度,更有助于良性發(fā)展。
例如如果C++社群都能明白這種潛哲學(xué)從何而來,或許也就會漸漸走向更好的發(fā)展了。
我用一個例子來說明這一點:你平時遍歷一個數(shù)組,或一個容器的時候是怎么做的?
for(std::vector::iterator it = v.begin(); it != v.end(); ++it) {…}
這種做法很臃腫。其實你的邏輯是“對v中的每個元素,做…事情”,你知道大多數(shù)其它流行的語言中都有內(nèi)建的for_each。那C++中就沒有了嗎?有。
STL的for_each算法,于是你寫: struct MyOp{void operator()(int& i){…}};
std::for_each(v.begin(), v.end(), MyOp());
這個方案實際很差。一是你還是得寫v.begin()、v.end(),二是你得為此定義一整個新類。三是這個新類并不在你使用這個新類
(for_each被調(diào)用)的點上,因為局部類不能做模板參數(shù)。 你要的是lambda function: for_each(v.begin(),
v.end(), <>(int& i){ …}); 可是C++98沒有。 你要的是內(nèi)建foreach:
for(int& i : v) {…} 可是C++98沒有。
鑒于循環(huán)結(jié)構(gòu)是編程中最常出現(xiàn)的結(jié)構(gòu)之一。這個問題其實還是比
較惱人的,如果你覺得不惱人可能只是因為你適應(yīng)性習(xí)慣了,這未必是好事。比如每次都要寫std::vector::iterator就很讓人惱火,如果我
換個容器,就要修改一堆std::vector<…>。那用typedef行不行啊?行。可仍然還是需要寫一次typedef,我很懶,我什
么多余的無用代碼都不想寫。要知道,每多出一行無用的(并非因表達(dá)思想所需要才出現(xiàn))的代碼,就增加一點維護(hù)負(fù)擔(dān),這也正是為什么語言的表達(dá)力如此重要的
原因。
那怎么辦?如果我告訴你,C++98里面其實你也可以寫: foreach(int& i , v){ …}
你怎么想? 廢話。當(dāng)然是求之不得了。有這么簡潔的表達(dá)方式誰還不想用啊。
我需要告訴你的另一個事實是。為了在C++98里面幾近完美地實現(xiàn)這個特性,有人把標(biāo)準(zhǔn)的角落挖了個底朝天。不,我不是在為鉆語言細(xì)節(jié)找理由,我只是想告
訴你,許多人所認(rèn)為的鉆語言細(xì)節(jié)的做法,其實一開始大多是由用戶實際需求驅(qū)動的,這個foreach設(shè)施被C++程序員們試圖實現(xiàn)了N遍N種做法,可見需
求之強(qiáng)烈??上Ы^大多數(shù)實現(xiàn)都遠(yuǎn)遠(yuǎn)稱不上好用,就連現(xiàn)在這個實現(xiàn)的作者也早在03年在CUJ上發(fā)了一個實現(xiàn),也稱不上好用。是后來又契而不舍才實現(xiàn)了最終
這個真正好用的版本的。
我想說的是,上面這個美好的foreach,當(dāng)然人人都想用。但問題是要在C++98下實現(xiàn)它只能靠挖標(biāo)準(zhǔn),這是唯一的途徑。要不然就得等語言進(jìn)化,并忍
受若干年,誰愿意?況且這個foreach設(shè)施還能作占位符,在C++09來臨之前兢兢業(yè)業(yè)履行其職責(zé),C++09加入內(nèi)建foreach支持之后只消用
正則表達(dá)式搜索全局替換,就OK了,沒有任何的升級麻煩。
再舉一個經(jīng)典的例子:STL里面的traits。其實traits不應(yīng)該是
traits。traits最自然的實現(xiàn)方式應(yīng)該是C++09的concept。但STL需要用到靜態(tài)dispatch技術(shù)啊,那怎么辦?要么用
traits(增加語言復(fù)雜性),要么不用(顯然不行)。
再舉個經(jīng)典的例子:模板元編程。模板元編程有啥用?日常開發(fā)者八輩子估計也用
不到。但真的嗎?沒錯,日常開發(fā)者并不會直接用到。但是,由模板元編程支持的各個boost子庫呢?被選入C++0x的TR1的各個子庫呢(間接用到)?
那日常開發(fā)者用不用學(xué)模板元編程呢?不用學(xué),根本不用學(xué),這么復(fù)雜的技術(shù)學(xué)什么呢?也就是點技巧上的東西。那為什么偏有人學(xué)呢?待會再說。
還有大量的例子就不一一列了。其實STL的traits技術(shù)已經(jīng)能夠說明問題了。如果你仔細(xì)看一看,你會發(fā)現(xiàn),那些所謂的利用C++黑暗角落的技術(shù),幾乎
無一不是出現(xiàn)在庫開發(fā)里面的,而之所以出現(xiàn)在庫開發(fā)里面,是因為庫開發(fā)中的需求驅(qū)動的——為了開發(fā)出更好的庫。難道你不想用更好的庫?
哦,說到“更好的庫”,肯定會有同學(xué)有意見了。
C++98都快十年了,標(biāo)準(zhǔn)庫還是只有那一套STL。庫進(jìn)展緩慢,到現(xiàn)在GUI庫也沒有一個標(biāo)準(zhǔn),都是四分五裂各自為營。網(wǎng)絡(luò)庫也是、文件系統(tǒng)庫也是、日志庫也是…不過這個問題已經(jīng)是另一個問題了,容后再說。
問題是,“沒有標(biāo)準(zhǔn)的庫”并不意味著“C++的庫不好”,后者也并不意味著“那些晦澀的技巧并沒有提升庫的質(zhì)量”,這個邏輯上的兩環(huán)都不對。實際上,人
們所謂的“晦澀而復(fù)雜的技巧”其實正是為了提升庫的質(zhì)量而被挖掘出來的。traits技術(shù)提升庫的效率(靜態(tài)轉(zhuǎn)發(fā)),type
erase技術(shù)使得boost::function可以接受任何簽名為void()的函數(shù)(靈活性),包括仿函數(shù),包括boost::bind后的函數(shù)。
type list技術(shù)使得boost::tuple能夠接受可變數(shù)目的模板參數(shù)。policy-based
design使得可以對一個設(shè)施的功能進(jìn)行正交分解… 就算把所有流行的C++
tricks都列出來,你也會發(fā)現(xiàn),其實它們幾乎每一個都對應(yīng)了至少一個實際應(yīng)用。而實際應(yīng)用需求哪來的?庫設(shè)計的需求。但歸根到底,是使用庫的人——終
端程序員——的需求。(效率、靈活性、抽象表達(dá)力,哪一樣不是終端程序員的實際需求呢?)
再舉個實例,有同學(xué)說,我只要寫簡單的代碼。問題是,簡單不意味著單純。簡單意味著在更高抽象層次上面編程,后者是要靠好的庫抽象才能達(dá)到的。借用《Extended STL》里面的一個例子:
DIR* dir = opendir(".");
if(NULL != dir){
struct dirent* de;
for(; NULL != (de = readdir(dir)); )
{
struct stat st;
if( 0 == stat(de->d_name, &st) &&S_IFREG == (st.st_mode &S_IFMT)) {
remove(de->d_name);
}
}
closedir(dir);} 這段代碼刪除當(dāng)前目錄中所有文件。
readdir_sequence entries(".", readdir_sequence::files);
std::for_each(entries.begin(), entries.end(), ::remove); 這段代碼做同樣的事情——哪個更簡單?
那問題是,為什么發(fā)展到后來,“鉆語言細(xì)節(jié)”成了社群的潛在哲學(xué)呢?
這其實是一個心理學(xué)上的問題,跟語言沒有關(guān)系,跟C++的初衷更沒有關(guān)系。從心理上,在同一個領(lǐng)域,如果另一個人比你懂得更多,你就會傾向于佩服他,這時
另一個人懂的東西有多大的用處其實并不那么重要,人對自己不懂的東西總是有一種敬畏感的。
C++里面有那么多的tricks,其實日常編程中要用到的trick少之又少,日常編程絕大多數(shù)都以復(fù)用庫為主,而那些tricks就隱藏在庫里面。除非你是庫的設(shè)計者,否則很多的tricks根本就無需關(guān)注。
另一方面,寫作C++書籍的大多數(shù)都是C++庫的設(shè)計者,這就給予了許多C++書一個有偏見的視角,大量庫設(shè)計中才會用到的技術(shù)被介紹出來,而社群對這
些牛人又都是唯馬首是瞻的。(其實我覺得一本Bjarne的《The C++ Programming
Language》加上一本Herb&Alexandrescu的《C++ Coding
Standard》對于日常程序員來說,真的足夠了。)
此外,人總是好奇的,在C++里面有那么多的被“發(fā)明”的好玩技術(shù),怎么可能不會有人去追捧呢。另一個動機(jī)則是學(xué)了這些技術(shù)有立竿見影的炫耀效果,比如在
論壇上。這可比編寫可維護(hù)代碼的才能容易表現(xiàn)多了——人自然是更傾向于去關(guān)注那些更容易拿來表現(xiàn)和炫耀的東西的。退一步說,就單單是“發(fā)明”一項新的語言
特性組合運用技巧都能帶來純粹的成就感,因為你又在現(xiàn)有語言框架下作出了一個創(chuàng)舉,你做了別人做不到的。而作為學(xué)習(xí)者,你可能會因為發(fā)現(xiàn)原來自己理解的一
塊土地上還有不知道的東西而感到興奮和新奇,這種興奮和新奇感往往是學(xué)習(xí)的真正原動力。至少,對于我來說,當(dāng)年讀《Modern C++
Design》時正是這樣一種感覺,我想有和我一樣感覺的人肯定不在少數(shù)。
再來,一個是在人前看不見摸不著的編碼能力,另一個是對
handy的技巧的掌握。作為一個學(xué)習(xí)者,傾向于學(xué)習(xí)后者,因為后者學(xué)起來更容易,而且也往往更有趣。學(xué)到了之后能夠得到跟解決重大問題同等的成就感——
看看《Effective C++》系列受到的追捧就知道了。
再來,當(dāng)你面臨兩個問題,一個是如何建立一個高質(zhì)量的庫(大),一個是如
何修正庫里面的小bug(如vector里面某個成員函數(shù)的異常保證問題)。如果你有一份時間,你更傾向于把它花在什么地方?人在心理上總是傾向于走“捷
徑”的,體現(xiàn)在這個問題上面便是更傾向于對付耍點小聰明就解決的小問題,并獲得甚至并不亞于解決大問題的成就感。小問題的另一個吸引人的地方在于它耗時
短,更“趁手”,它不需要你閉關(guān)苦苦編碼幾個月弄出一個框架來而且還不一定能成。所以這就給人一種錯覺,C++社群只知道爭論枝節(jié)問題,不知道實干庫。
哦,不是錯覺,這的確是大部分的現(xiàn)狀,但這個現(xiàn)象其實并不僅僅止于C++社群,這是人心理的共性造成的,這也就是為什么無論在哪個語言社群你都會看到爭論
最多的都是些“小問題”的原因。(當(dāng)然,無論在哪個學(xué)科,也還總是有牛人去啃難啃的骨頭的。但這并不是廣大民眾的狀況。)
以上種種原因共同造就了C++社群的這種心態(tài)。
這其實跟C++的“教義”沒有關(guān)系。C++如果有教義的話也是實用為上。這種現(xiàn)狀是自發(fā)
產(chǎn)生的,它的動力來源于人的心理。如果Java語言有各種各樣的特性組合,且這些特性組合能夠某些時候滿足開發(fā)中的實際需求的話,也是一樣會出現(xiàn)這樣的情
況的(事實上一個小小的Java
Closure就已經(jīng)引起了大量口水了)。某種程度上,LISP里面用函數(shù)來實現(xiàn)自然數(shù)系統(tǒng),也是一樣的道理,你敢說,你第一次看到它的時候,不驚嘆?人
之常情而已。
那這種哲學(xué)對不對?廢話。當(dāng)然不對。不但不對,而且有害。很多C++日常開發(fā)者在學(xué)習(xí)庫開發(fā)技巧上浪費了很多時間,掌握了根本用不到的技術(shù),而且這些技
術(shù),不如稱為技巧,可能還會隨著語言進(jìn)化變得根本無用武之地。還不如好好學(xué)學(xué)如何讓自己的代碼更KISS呢,基本的編碼準(zhǔn)則要遠(yuǎn)遠(yuǎn)重要得多,正如我剛才說
的,日常開發(fā),一本《The C++ Programming Languag》加一本《C++ Coding Standard》足夠了。
另外,說到語言進(jìn)化順便說一句,語言進(jìn)化的職責(zé)之一便是廢黜繁復(fù)的技巧,取代以直接表達(dá)思想的語言特性。而C++0x真正在履行這一職責(zé)。 最后來說一說前面留下來的一個問題:為什么C++設(shè)計的初衷——“不要固執(zhí)于完美”——某種程度上帶來了這個局面呢?
因為正是因為這種理念的指導(dǎo),有不少語言特性從理論上都是不完備的:比如有copy語意沒有move語意(有左值引用沒有右值引用),于是
Alexandrescu用Mojo框架來解決;比如支持可變參數(shù)的函數(shù)調(diào)用卻不支持可變參數(shù)的模板參數(shù)列表,導(dǎo)致用元編程來解決;比如不支持構(gòu)造函數(shù)轉(zhuǎn)
發(fā),導(dǎo)致必須factor出一個公共的initialize函數(shù)來;比如不支持強(qiáng)類型的enum,結(jié)果用一大堆宏結(jié)合類來解決;比如不支持
initializer
list,結(jié)果用復(fù)雜的模板技術(shù)來實現(xiàn)某種類似的初始化方式;比如不支持auto和typeof,結(jié)果用更復(fù)雜N倍的模板元編程技術(shù)來實現(xiàn)一個模擬;比如
不支持內(nèi)建的alignment指示,導(dǎo)致Alexandrescu在實現(xiàn)類型安全的union的時候用盡了模板元編程技巧;比如不支持內(nèi)建的
foreach,結(jié)果借助于詭異的語言角落實現(xiàn)了一個幾近完美的模擬;比如不支持內(nèi)建的concept,導(dǎo)致使用模板技巧來實現(xiàn)也算能用的concept
檢查…這個列表可以一再延長下去,C++中這樣的示例太多了。C++的不完美導(dǎo)致了各種各樣的技巧應(yīng)運而生,哦,不,應(yīng)該說,應(yīng)實際需求而生。這從另一個
側(cè)面正說明了一點—— C++太需要進(jìn)化了!
Fallacy #2 ——C++委員會過分關(guān)注一些不切實際的語言特性,而不關(guān)心標(biāo)準(zhǔn)庫的擴(kuò)充
比起第一個fallacy來,這個倒容易解釋清楚了。人家Bjarne在文章和訪談里面一再強(qiáng)調(diào),C++從來都是把庫設(shè)計放在首位的(這句話其實就意味
著,是把最終開發(fā)者放在首位的——什么?你難道不用庫?),但是C++群體是一個分散多樣的群體,而且沒有大公司的財力支持。前者意味著眾口難調(diào)(標(biāo)準(zhǔn)化
過程困難),后者意味著不能集中精英的人力(boost庫的開發(fā)都是由大家業(yè)余時間完成的)來搞出個百萬美元的免費庫來。此外個人用業(yè)余時間來開發(fā)庫還意
味著往往沒有足夠的精力來對庫進(jìn)行精化改善,導(dǎo)致庫的質(zhì)量不佳或者干脆停滯(這樣的C++庫案例很多)。比如日志庫吧,沒有一打也有半打,但由于都是個人
業(yè)余開發(fā),所以沒有精力做到盡善盡美,唯一一個往boost提交的是John
Torjo(也是個牛人)寫的,不過一年前被reject之后就沒了動靜。你難道怪人家?人家又不是你雇來的。
但說到底,還是錢的問
題,眾口難調(diào)還是終究能調(diào)的(boost發(fā)起的初衷便在于此)。但沒有錢,鬼才跟你推磨呢。 不過好消息是據(jù)說boost明年能拿到fund:-)
應(yīng)該能把boost狠狠boost一把。
至于“C++委員會過分關(guān)注一些不切實際的語言特性”就不知從何說起了。首先,前文已經(jīng)明確說明語言進(jìn)化的重要性以及實用性,這說明語言進(jìn)化根本不像人們
認(rèn)為的那樣“不切實際”,而是與實用休戚相關(guān)的。其實從根本上,語言進(jìn)化就是為了帶來更好的庫,以及更好的代碼(包括日常編碼),這一點跟大伙殷殷企盼著
標(biāo)準(zhǔn)庫其實并不相左。此外還有一點就是,討論語言特性比實際去開發(fā)庫要花更少的精力,這兩者花的精力其實不在一個數(shù)量級上,開發(fā)一個庫出來要難得多得多,
所以就造成了一種假象——“委員會的那幫家伙只知道倒騰語言”。這個論點錯在了兩個地方,一,倒騰語言是必要的。二,他們并非只知道倒騰語言,只是庫的問
題要艱難得多,沒錢,人家難道砸鍋賣鐵給你開發(fā)標(biāo)準(zhǔn)庫嗎?
有同學(xué)說,我只要一個能用的庫就行了。但問題是,標(biāo)準(zhǔn)庫能隨便嗎?標(biāo)準(zhǔn)庫之所
以不能隨便,是因為像這樣受眾極其廣泛的庫可是要負(fù)責(zé)任的——將會有百萬千萬行代碼都依賴它。如果標(biāo)準(zhǔn)庫里面有bug,將會出現(xiàn)幾百萬上千萬行
workarounds,這些workarounds依賴于庫的bug,為了保持向后兼容性,標(biāo)準(zhǔn)庫甚至都不能修正這些bug。就連STL這樣漂亮的抽
象,迭代器區(qū)間還是闖了禍。另一方面,如果只是需要一個能用的庫,C++社區(qū)有大量“能用”的庫。姑且不說boost里面的了。
Fallacy #3 ——C++的強(qiáng)處在于什么都能做
一個最常見的論調(diào)就是,java的虛擬機(jī)也是C++做的,于是得出結(jié)論,java比C++弱,java沒有C++好。
姑且不說“好”的定義標(biāo)準(zhǔn)是什么。就算java的虛擬機(jī)做的,那C++的第一個編譯器還要用C寫呢。C庫里面的某些成分還要用匯編寫呢。這個論據(jù)是站不住
腳的。 其實,持這種論點的人是站錯了位置,問錯了問題。
關(guān)鍵的問題不是一門語言能做什么,因為說到能做什么,匯編什么都能做。而是
“在某個特定的領(lǐng)域,哪門語言表現(xiàn)更好”,人們的需求幾乎總是對著某個特定的領(lǐng)域的。后者才是真正matter的問題。
從這個角度看,C++的市場其實只在效率這一塊。有人可能會說,那效率這一塊有C啊。問題是,C的抽象機(jī)制太弱。寫架構(gòu)簡單的應(yīng)用,或者寫一些核心的(如
驅(qū)動程序),沒有面向?qū)ο蠼Y(jié)構(gòu)的程序,容易。完全可以用C。但涉及到大型系統(tǒng),比如.NET基層架構(gòu),一些3D游戲。必須用到面向?qū)ο蠡蚧趯ο缶幊痰念I(lǐng)
域,C在代碼組織和抽象方面的弱點就暴露出來了。比如用C和宏來實現(xiàn)所謂OO,就正說明了C的抽象機(jī)制的薄弱。
但是,C++的領(lǐng)土
基本也就在這些地方了。簡而言之就是所有“效率重要,且同時需要好的抽象機(jī)制的應(yīng)用領(lǐng)域”。因為C++的優(yōu)勢就是無損效率的實現(xiàn)更好的抽象。
那C++既有效率又有更好的抽象機(jī)制,為什么C++不能取代java、不能取代python,不能取代ruby?或者至少當(dāng)C++進(jìn)化到更好的階段的時
候,比如C++0x就是一個大的進(jìn)展(在語言方面),為什么作為一門語言,不能取代那些嚴(yán)重“偏科”的語言呢?
原因有兩方面。一方面,
正因為“偏科”,所以有些語言才能在它們擅長的領(lǐng)域做得更好,乃至做到最好。“偏執(zhí)狂才能生存”。人們的需求幾乎總是在特定領(lǐng)域的,你說這時候人是愿意選
用一門專門為這個領(lǐng)域而生的語言(ruby),還是愿意用一門general-purpose的語言(C++)?另一方面,就算C++在抽象機(jī)制上進(jìn)化到
了非常好,乃至于能在某些特定領(lǐng)域也表現(xiàn)不菲的話,由于市場早就被別的語言侵占,別的語言已經(jīng)有了成百上千萬行的代碼基,別的語言的庫已經(jīng)發(fā)展到非常豐富
的程度,別的語言的相關(guān)人才教育已經(jīng)一代又一代,所以結(jié)果還是沒得拼。
其實,從另一個角度來說,C++何嘗不也是一門偏執(zhí)的語言呢?C++的偏執(zhí)就是效率,C的偏執(zhí)也是效率,但C++提供更好的抽象,因此在這一塊(效率+抽
象),C++比C有優(yōu)勢。
C++的領(lǐng)土已經(jīng)鑄成,另一方面,C++的領(lǐng)土在可見的未來也不大可能縮水了。這是C++的現(xiàn)實,這個現(xiàn)實,至少在Bjarne看來,也沒什么不好,因為
它正反映了C++當(dāng)時設(shè)計的意圖——更好的C。我們也不用趕鴨子上架,非拿C++和其它語言比——適用的場合本就不同,沒得比。 Fallacy #4
…
事不過三,就此打住。況且,這三條難道還不夠嗎?如果你想到還有什么fallacy要補充的,請不吝回帖:) 我會考慮加到文章里面的:)