最近,有人在推特上討論編程語(yǔ)言如何才能取得成功。有人提到了社區(qū)、營(yíng)銷(xiāo)、低成本的開(kāi)發(fā)人員等等。
然而,我認(rèn)為這些因素與編程語(yǔ)言的成功并沒(méi)有太大關(guān)聯(lián)。20 多年來(lái),我使用過(guò)很多編程語(yǔ)言,也反思過(guò)它們的優(yōu)缺點(diǎn)。在本文中,我想總結(jié)一些常見(jiàn)的模式,說(shuō)明為什么有些語(yǔ)言取得了成功,而有些語(yǔ)言則失敗了。
如果編程語(yǔ)言沒(méi)有解決任何實(shí)際的開(kāi)發(fā)人員問(wèn)題,那么也走不長(zhǎng)遠(yuǎn)。成功的語(yǔ)言都會(huì)解決困擾開(kāi)發(fā)人員的問(wèn)題。在早期,性能是一個(gè)主要問(wèn)題,因?yàn)槟菚r(shí)的計(jì)算機(jī)真的很慢。C 編程語(yǔ)言之所以流行起來(lái),很大程度上是因?yàn)槿藗兛梢岳?C 編寫(xiě)速度非??斓拇a。相比之下,LISP 和 Smalltalk 由于性能低下,其發(fā)展就非常有限。
C++ 流行是因?yàn)樗鉀Q了很多 C 代碼中的問(wèn)題,而 Java 是因?yàn)樗鉀Q了許多 C++ 的問(wèn)題。就像 Swift 解決了許多 Objective-C 的問(wèn)題一樣。Perl(雖然現(xiàn)在不怎么流行了)變得非常流行,是因?yàn)樗鼧O大地簡(jiǎn)化了 shell 編程。
從很多方面來(lái)說(shuō),Python 之所以流行,是因?yàn)樗槍?duì) Perl 帶來(lái)的混亂提供了一種解決方案。而Ruby 也因同樣的原因廣受歡迎。從某種程度上說(shuō),它們通過(guò)不同的方式解決了 Perl 的痛點(diǎn),同時(shí)又沒(méi)有放棄許多 Perl 的優(yōu)點(diǎn)。說(shuō)到這里,我們不得不提兼容性和熟悉度。
許多語(yǔ)言都利用 C 來(lái)解決問(wèn)題。最有名的例子就是 C++。它使用的語(yǔ)法與 C 非常相似,甚至可以與 C 的代碼兼容,因此你可以將已有的 C 代碼與新的 C++ 代碼混合起來(lái)使用。這樣采用 C++ 的門(mén)檻就會(huì)降低。
Java雖然沒(méi)有提供源代碼兼容性,但它提供了熟悉度。它大量借用了許多人熟悉的 C/C++ 語(yǔ)法,同時(shí)簡(jiǎn)化了許多概念。Java 誕生之時(shí),面向?qū)ο蠓浅A餍?,它借助了面向?qū)ο蟮臒岢?,并宣稱Java 甚至不允許編寫(xiě)自由函數(shù)。一切都必須是方法;這是面向?qū)ο蟮腏ava!雖然這是個(gè)有點(diǎn)愚蠢的噱頭,但從營(yíng)銷(xiāo)的角度來(lái)看,效果非常好。這種說(shuō)法很容易被人們接受,即便邏輯有問(wèn)題。
JavaScript的創(chuàng)建者注意到了 Java 的廣泛流行,并采納了 Java 風(fēng)格的語(yǔ)法。因此,JavaScript 通過(guò)熟悉的語(yǔ)法推動(dòng)了采用。即便語(yǔ)義上完全不同也不重要。人們是膚淺的,如果語(yǔ)法看起來(lái)很熟悉,人們就會(huì)覺(jué)得這門(mén)語(yǔ)言很容易學(xué)習(xí)。
而Perl、Ruby 和 Python 像是存在于平行宇宙中。Unix 不僅帶來(lái)了 C 編程,還帶來(lái)了shell 腳本。對(duì)于簡(jiǎn)單的任務(wù)和自動(dòng)化,shell 腳本明顯比 C 程序更有優(yōu)勢(shì)。人們紛紛開(kāi)始編寫(xiě)大型 shell 腳本,然而 shell 語(yǔ)法不太適合大型腳本。于是,救星 Perl 出現(xiàn)了。它是一種更合適的語(yǔ)言,而且對(duì)于熟悉shell 腳本的人來(lái)說(shuō),Perl 的語(yǔ)法非常熟悉。因此,任何習(xí)慣使用 Bash shell 的人都可以輕松掌握 Perl。
于是,Perl 成為了文本處理界的“瑞士軍刀”。它有正則表達(dá)式,你可以與之交互。它與C、C++ 和 Java 有著不同的市場(chǎng)。
Python和Ruby 的成功也借鑒了這類經(jīng)驗(yàn)。它們也是可以在 Unix shell 中輕松運(yùn)行的 shell 語(yǔ)言。雖然二者在 Bash 之外也有很多用途,但它們的語(yǔ)法讓 Perl 程序員倍感親切。它們吸引了熟悉非腳本語(yǔ)言(比如 Java)的程序員,同時(shí)對(duì) shell 也很友好。
因此,它們也建立在熟悉的基礎(chǔ)之上,盡管源代碼不兼容。
令人驚訝的是,通過(guò)壟斷的方式將某種語(yǔ)言推向頂峰的做法也很常見(jiàn)。例如,作為 Web 語(yǔ)言,JavaScript 設(shè)計(jì)得相當(dāng)隨便。但由于它成為了網(wǎng)頁(yè)的標(biāo)準(zhǔn),因此壟斷了客戶端 Web 開(kāi)發(fā)。隨著 Web 越來(lái)越流行,JavaScript 的普及度也水漲船高。
Objective-C和Swift 的情況也完全相同。在 iPhone 大受歡迎、人們愛(ài)上智能手機(jī)應(yīng)用之前,Objective-C 是一種相對(duì)難懂的語(yǔ)言,幾乎只有蘋(píng)果生態(tài)系統(tǒng)使用。我是早期的粉絲之一。事實(shí)上,在 Objective-C 被納入蘋(píng)果之前,我就是它的粉絲,該語(yǔ)言來(lái)自 NeXT 公司,是喬布斯在 80 年代被踢出蘋(píng)果公司后創(chuàng)辦的。
對(duì)于我來(lái)說(shuō),Objective-C 的吸引力在于它結(jié)合了 C 的性能與 Smalltalk 優(yōu)雅的對(duì)象模型。當(dāng)然,這種只有技術(shù)宅男才會(huì)關(guān)注的點(diǎn)并沒(méi)有對(duì)大眾帶來(lái)太多吸引力。真正讓 Objective-C 得到發(fā)展的是iPhone。Mac OS X 基于 NeXTSTEP,而 iPhone OS 基于 Mac OS X。在 NeXT 和 OS X 的世界中,Objective-C的地位如同 Unix 系統(tǒng)中的 C 一樣,完全主宰一切。
事實(shí)上,我們可以說(shuō) C 流行起來(lái)的原因也大抵相同。就像 iPhone 的流行成全了 Objective-C 一樣,Unix 的流行也將 C 推向了巔峰。Unix 中所有重要的功能都是用 C 編寫(xiě)的,因此如果你想攻克 Unix,首先必須學(xué)習(xí) C。這就是 70 年代人們紛紛開(kāi)始C 的原因。
Swift的發(fā)展思路也大致相同。蘋(píng)果宣布 Swift 是未來(lái),它將取代 Objective-C。這就等于保證了該語(yǔ)言的巨大市場(chǎng)份額。
雖然上述因素可以讓編程語(yǔ)言達(dá)到一定的流行度,但可能還不足以解釋為什么這些語(yǔ)言會(huì)如此流行。通常,這些語(yǔ)言中的某些功能可以構(gòu)建某款殺手級(jí)的應(yīng)用。
例如,Ruby 具有強(qiáng)大的元編程功能。因此,有人構(gòu)建了 Ruby on Rails,而這反過(guò)來(lái)又推動(dòng)了 Ruby 的發(fā)展。
對(duì)于Objective-C 和 Swift,我猜你會(huì)說(shuō)殺手級(jí)應(yīng)用是iPhone 應(yīng)用。
對(duì)于JavaScript,我們很難得出相同的結(jié)論,因?yàn)槠湓?Web 的壟斷始終可以確保主導(dǎo)地位。然而我認(rèn)為,可以說(shuō) Node.js 的開(kāi)發(fā)鞏固了 JavaScript 的地位。
雖然長(zhǎng)期以來(lái) Python 一直很受歡迎,但真正讓它走紅的是數(shù)據(jù)科學(xué)與機(jī)器學(xué)習(xí)的興起。這些領(lǐng)域需要交互式解決方案。編譯語(yǔ)言不太適合。Python 擁有 NumPy 以及其他解決方案,并且沒(méi)有面臨太多競(jìng)爭(zhēng)。JavaScript 被鎖到了 Web 上。Perl 是一種非常難讀懂的語(yǔ)言。Matlab 走的是商業(yè)路線,而且年頭太久遠(yuǎn)。并且二者都沒(méi)有提供面向?qū)ο缶幊袒蚝瘮?shù)式編程,只是簡(jiǎn)單的過(guò)程式編程。Lua 主要適用于嵌入,沒(méi)有豐富的庫(kù)生態(tài)系統(tǒng)。R 有古怪的語(yǔ)法和混亂的生態(tài)系統(tǒng),對(duì)程序員沒(méi)有吸引力。
然而, R 相對(duì)發(fā)展得還不錯(cuò),部分原因是數(shù)據(jù)分析的興起,以及軟件行業(yè)對(duì)大數(shù)據(jù)的癡迷。
一門(mén)編程語(yǔ)言可以解決很多痛點(diǎn),并提供很大的優(yōu)勢(shì),但如果不易于使用和學(xué)習(xí),也走不長(zhǎng)遠(yuǎn)。請(qǐng)注意,易學(xué)和易用并不一定是一回事。舉個(gè)例子,C++ 是一種極其復(fù)雜的語(yǔ)言,而且使用也很不方便。那么,它是如何變得如此受歡迎的呢?
因?yàn)樗柚?C 的成功。對(duì)于有 C 經(jīng)驗(yàn)的人來(lái)說(shuō),學(xué)習(xí) C++ 不會(huì)特別難。而且當(dāng)初 C++ 流行起來(lái)的時(shí)候,它遠(yuǎn)比如今簡(jiǎn)單得多。此處,我們還要提一下臨界質(zhì)量和社區(qū)的概念。一個(gè)成功會(huì)推動(dòng)另一個(gè)成功。某種語(yǔ)言一旦擁有龐大的社區(qū)、教程、大量用它編寫(xiě)的軟件、愿意招聘的公司,那么無(wú)論該語(yǔ)言存在何種缺陷,都會(huì)得到發(fā)展。但是也不能將 C++ 的成功完全歸功于社區(qū),因?yàn)檫@并不能解釋最初它是如何俘獲社區(qū)的。
還有一點(diǎn)也很重要,易用性往往是表面上的。例如,Objective-C 是一種比 C++ 簡(jiǎn)單得多的語(yǔ)言。然而人們通常會(huì)認(rèn)為 C++ 更容易學(xué)習(xí),因?yàn)樗恼Z(yǔ)法看起來(lái)更熟悉。熟悉感是強(qiáng)大的驅(qū)動(dòng)力。
如今的 Java 可能并不是一種簡(jiǎn)單的語(yǔ)言,但在它剛出現(xiàn)時(shí),很多改進(jìn)都超過(guò)了 C++。開(kāi)發(fā)人員不必了解引用、指針、指向指針的指針、地址運(yùn)算符以及各種導(dǎo)致 C++ 開(kāi)發(fā)復(fù)雜化的底層概念。
在這方面,90 年代的 Go 編程語(yǔ)言也有類似的感覺(jué)。它是一種非常簡(jiǎn)單的小型語(yǔ)言,但是沒(méi)有像 Java 那樣受到面向?qū)ο?炒作的影響。相反,它努力遵循 C 的理念。我記得當(dāng)初 Go 剛問(wèn)世不久我就嘗試了一下。當(dāng)時(shí)我是一名 C++ 開(kāi)發(fā)人員,但我用 Python 編寫(xiě)了一些小型命令行工具,來(lái)簡(jiǎn)化我的工作流程。
我記得,我只用了短短幾天就學(xué)會(huì)了 Go。我很驚訝它的速度竟然如此之快。對(duì)于接觸過(guò) C 和 Python 編程的人來(lái)說(shuō),Go 的庫(kù)和語(yǔ)法似乎都很熟悉。幾乎有點(diǎn)像使用腳本語(yǔ)言。我記得,很快 Go 就取代 Python,成為我編寫(xiě)小工具的首選語(yǔ)言。靜態(tài)類型檢查有助于發(fā)現(xiàn) bug,而不會(huì)像 C++ 那樣扼殺生產(chǎn)力。當(dāng)時(shí)在我看來(lái),Go 必然會(huì)成功。它不僅易學(xué)、熟悉、而且性能良好,并解決了真正的痛點(diǎn),比如并發(fā)等。
那時(shí),我實(shí)際上并不關(guān)心并發(fā)。我只是在比較 Julia、C#、Java、Erlang 和 Swift 的并發(fā)系統(tǒng)時(shí)嘗試了 Go 并發(fā)。那時(shí)我才意識(shí)到 Go 的提升有多明顯。
然而,我認(rèn)為 Python、Ruby 和JavaScript 的興起,很大程度上也要?dú)w功于學(xué)習(xí)這些語(yǔ)言的簡(jiǎn)單性。
說(shuō)起未能成功的語(yǔ)言,我不禁會(huì)想起 Haskell、Standard ML、OCaml、F#、LISP、Scheme、D 和 Smalltalk。這些語(yǔ)言都很棒,可以解決實(shí)際問(wèn)題。然而,盡管經(jīng)過(guò)了多年的努力,它們始終未能取得任何進(jìn)展。為什么呢?
Haskell是一種面向各種編程極客的語(yǔ)言。從很多方面來(lái)看,我都像是會(huì)寫(xiě)大量夸贊 Haskell 有多么了不起的文章,并再三預(yù)言 Haskell 革命即將來(lái)臨。然而,我?guī)缀鯊奈磳?xiě)過(guò)關(guān)于 Haskell 的文章。為什么?
也許是因?yàn)槲乙彩?UX 的忠實(shí)粉絲,有時(shí)會(huì)寫(xiě)一些有關(guān)易用性和用戶界面設(shè)計(jì)的文章。從某種數(shù)學(xué)和技術(shù)的角度來(lái)看,Haskell 看起來(lái)像是天才的杰作。然而,從易用性的角度來(lái)看,我覺(jué)得它不及格。
沒(méi)錯(cuò),它具有數(shù)學(xué)優(yōu)雅和簡(jiǎn)單性,完全不同于 C++ 的混亂。然而,高級(jí)抽象數(shù)學(xué),無(wú)論多么優(yōu)雅,都不是普通人可以輕松掌握的。相反,盡管英語(yǔ)十分混亂,人們還是可以學(xué)習(xí)英語(yǔ)。很多英語(yǔ)的拼寫(xiě)毫無(wú)邏輯,缺乏一致性。然而,人們可以容忍這些問(wèn)題。盡管微積分在概念上更簡(jiǎn)單,但普通人卻完全掌握不了。
這就是這些語(yǔ)言失敗的地方。通常,它們都具有數(shù)學(xué)之美,但它們的構(gòu)建方式并不適合我們愚鈍的大腦。這些語(yǔ)言的知音人可能會(huì)覺(jué)得意難平??此茦O樂(lè)世界盡在掌握,只可惜有些人就是不開(kāi)竅。有時(shí),可能只是你太聰明了,無(wú)法理解普通人的難處。
我個(gè)人認(rèn)為 LISP、Scheme 和 Smalltalk 曾有過(guò)機(jī)會(huì)。對(duì)于這些語(yǔ)言,我認(rèn)為問(wèn)題不在學(xué)習(xí)有困難,而是缺乏熟悉度。與編程世界已經(jīng)習(xí)慣的語(yǔ)法相比,它們都包含一些奇怪的語(yǔ)法。另一個(gè)原因是生不逢時(shí)。它們根本無(wú)法達(dá)到當(dāng)時(shí)所需的性能。這些都是開(kāi)源項(xiàng)目和互聯(lián)網(wǎng)出現(xiàn)之前的時(shí)代。這導(dǎo)致這些語(yǔ)言出現(xiàn)了許多變種,阻礙了其發(fā)展。
盡管Smalltalk 有一個(gè)漂亮的開(kāi)發(fā)模型,但它太另類了。開(kāi)發(fā)基于修改鏡像而不是源代碼文件。它類似于直接操縱真實(shí)的數(shù)據(jù)庫(kù)。這與人們習(xí)慣的方式完全不同。無(wú)論有多么優(yōu)異都不重要,人們還是會(huì)選擇熟悉的語(yǔ)言。
參考鏈接:https://medium.com/geekculture/what-makes-a-programming-language-succeed-de7c0d15b7f9
聯(lián)系客服