框架成為新的編程語言的7種理由
譯文在 1980 年代,掀起一場乏味戰(zhàn)爭的最簡單方法,就是贊揚(yáng)你鐘愛的編程語言是最棒的。C、Pascal、Lisp、Fortran?程序員們花費(fèi)數(shù)個(gè)小時(shí)來詳細(xì)解釋關(guān)于精巧制作一條 if-then-else 語句的特定方式為什么優(yōu)于你的方式。
那是過去的事情了。今天,涉及語法和結(jié)構(gòu)的戰(zhàn)爭基本結(jié)束了,因?yàn)槭澜缫呀?jīng)匯總了一些簡單標(biāo)準(zhǔn)。在 C、Java 和 JavaScript 里,分號(hào)、花括號(hào)等之間的差異不大。關(guān)于類型和閉包的有趣爭論仍然存在,但是大部分是毫無意義的,因?yàn)樽詣?dòng)化在縮小差距。如果你不想定義數(shù)據(jù)類型,那么有一種可能,計(jì)算機(jī)將能準(zhǔn)確推斷出你的意思。如果你的老板想用 JavaScript、而你喜歡 Java,那么交叉編譯器【注1】將把所有靜態(tài)類型的 Java 代碼轉(zhuǎn)化成可以在瀏覽器運(yùn)行的最小化的 JavaScript。當(dāng)技術(shù)做后盾時(shí),為什么還有戰(zhàn)爭呢?
今天,有趣的戰(zhàn)斗發(fā)生在框架上。當(dāng)我在約翰·霍普金斯大學(xué)和其他院系成員規(guī)劃一門新課程時(shí),框架成了討論的重點(diǎn)。Angular 優(yōu)于 Ember?Node.js 就是一切嗎?
我們設(shè)計(jì)了一份調(diào)查課程,將探索最重要的軟件包的架構(gòu),這是互聯(lián)網(wǎng)的基礎(chǔ)。這是行動(dòng)的中心,這份調(diào)查課程的價(jià)值在于探索圍繞著當(dāng)今互聯(lián)網(wǎng)的、最重要的軟件包的架構(gòu)。
從這個(gè)意義上說,框架就是新的編程語言。它們就是當(dāng)代代碼被建立起來的最新思想、哲學(xué)和實(shí)用性。有些曇花一現(xiàn),不過大部分成為了編程的、新的基本構(gòu)成要素。下面是助長這種框架趨勢的七個(gè)方面,使得框架成為滋生乏味戰(zhàn)爭的新的最愛。
大部分代碼正和 API 串在了一起
過去編寫軟件,意味著調(diào)用你對編程語言的所有技能,以最大化壓榨代碼。掌握指針、函數(shù)和作用域是講得通的——代碼質(zhì)量取決于做正確的事情。如今自動(dòng)化處理了這方面的大多數(shù)事情。如果你在代碼里遺留了無用的語句,不要擔(dān)心,編譯器會(huì)去掉無用代碼。如果你讓指針吊著,垃圾回收器可能會(huì)找到它。
還 有,如今編碼實(shí)踐也不同了。大部分代碼現(xiàn)在都是一長串 API 調(diào)用。偶爾有一些 API 調(diào)用之間的數(shù)據(jù)重組,但是,甚至這些工作通常也有其它 API 來完成。幸運(yùn)的一些人在為我們機(jī)器的核心編寫更聰明的、位拆裂【注2】、指針雜耍之類的代碼,但是我們大部分人工作于更高的層次。我們在 API 之間簡單地運(yùn)行管道。
鑒于此,理解 API 的表現(xiàn)以及能做什么,就顯得更加重要。它接受哪種數(shù)據(jù)結(jié)構(gòu)?當(dāng)數(shù)據(jù)集增長較大時(shí),算法表現(xiàn)如何?類似這樣的問題,與關(guān)于語法或語言的問題比起來,更加集中在今天的編程里。的確,有大量工具簡化了某種語言從另一種語言調(diào)用一個(gè)程序。比如,把 C 資源庫鏈接到 Java 代碼,變得相應(yīng)簡單了。理解 API 才是重要的。
站在巨人的肩膀上,是值得的
假設(shè)你已經(jīng)成為了 Erlang 或另一種新語言的信徒。你認(rèn)為,它為編寫文檔、沒有 bug 的應(yīng)用提供了最好的平臺(tái)。這是優(yōu)秀的觀點(diǎn),但是你要花費(fèi)數(shù)年才能把可獲得的 Java 或 PHP 重寫為你最新選擇的語言。你的代碼最終可以顯著變得更好,但是值得花這些額外的時(shí)間嗎?
框 架讓我們對來到我們面前的那些艱難工作做出了改變。我們或許不喜歡他們選擇的架構(gòu),我們或許爭論于實(shí)現(xiàn)細(xì)節(jié),但是停止抱怨、找到和差異共存的方式才是更有 效的。繼承框架代碼庫里的所有精華和糟粕,是如此地容易。用你喜歡的新語言、自己編寫所有東西,而不采用某種更受歡迎的框架,這種強(qiáng)悍的方式和簡單地遵循 框架作者及其 API 比起來,不會(huì)讓你快速享受到新選擇的樂趣。
理解架構(gòu)是做什么的,而非語法
由 于大部分編碼都是串起 API 調(diào)用,因此沒有太多優(yōu)勢去學(xué)習(xí)語言的特質(zhì)了。當(dāng)然,你可以成為關(guān)于 Java 是如何初始化對象內(nèi)的靜態(tài)字段的專家,但是如果能夠搞清楚如何發(fā)揮 Lucence、JavaDB 或其它一堆代碼的威力,那才是更好的。為了深入理解 Objective-C 編譯器的優(yōu)化程序,你要花費(fèi)數(shù)月,但是學(xué)習(xí)最新的 Apple 核心資源庫的來龍去脈,你將真正讓代碼優(yōu)秀。你將更深入地學(xué)習(xí)框架吹毛求疵的細(xì)節(jié),而不是框架所依托的語言的語法。
我們的大部分代碼在資源庫的內(nèi)部循環(huán)中花費(fèi)了大量時(shí)間。搞清楚語言細(xì)節(jié)的正確性可以起到幫助,但是了解資源庫內(nèi)部發(fā)生了什么可以獲得顯著的回報(bào)。
算法主導(dǎo)
學(xué)習(xí)一門語言有助于你應(yīng)付隱藏在變量里的數(shù)據(jù),不過只是把你帶到了更遠(yuǎn)的地方。真正要克服的是,確保算法正確,它們通常被框架定義和實(shí)現(xiàn)了。
很 多程序員明白,重新實(shí)現(xiàn)標(biāo)準(zhǔn)算法和數(shù)據(jù)結(jié)構(gòu)是危險(xiǎn)的,也是浪費(fèi)時(shí)間的。你可能讓它更符合需求,但是你要冒著犯微妙錯(cuò)誤的風(fēng)險(xiǎn)??蚣芤呀?jīng)廣泛測試過多年了。 它們代表了軟件基礎(chǔ)設(shè)施的集體投資。當(dāng)弄明白“go off the grid”【注3】是什么意思時(shí),將其他人的辛苦勞動(dòng)扔在一邊,用你自己的雙手搭建一個(gè)算法小屋——其實(shí),沒有太多這種例子。
正確的做法是學(xué)習(xí)框架,學(xué)習(xí)如何使用它們來發(fā)揮你的最大優(yōu)勢。如果你選擇了錯(cuò)誤的數(shù)據(jù)結(jié)構(gòu),那么你就把一個(gè)線性工作變成了耗時(shí)的、輸入大小的二次函數(shù)。一旦你這樣做了,將是一個(gè)大麻煩。
糾正語法的編譯器和聰明的 IDE
我 應(yīng)該在代碼塊的最后一個(gè)語句后面加上分號(hào)嗎?分號(hào)是“分隔符”,還是“終止符”?語言設(shè)計(jì)者們花了大量時(shí)間來制作實(shí)施這些規(guī)則的分析器——猜猜怎樣——我 不關(guān)心。我關(guān)心的時(shí)候大概是在 10 年前,但是現(xiàn)在的 IDE 為我做了這部分工作。它們一直在身后看著我,當(dāng)我搞砸的時(shí)候就告訴我。我讓它們替我去考慮,把時(shí)間花在考慮關(guān)于代碼方面的大問題。IDE 是苦力、是處理這些瑣碎細(xì)節(jié)的編程助理。
自動(dòng)化已經(jīng)把我們從編程語法的單調(diào)乏味中拯救了。當(dāng)然,它們不能為我們做所有工作。我們?nèi)匀恍枰邆洳渴鹉欠N標(biāo)點(diǎn)符號(hào)的模糊思維。但是大部分時(shí)候,語言的這種細(xì)節(jié)已經(jīng)不重要了。
IDE 不僅對框架有幫助,還有一些小細(xì)節(jié)。它們提醒我們函數(shù)調(diào)用的參數(shù),它們甚至檢查數(shù)據(jù)是否為正確的類型。然后,我們應(yīng)該知道使用哪種函數(shù)、如何將它們組合在 一起。當(dāng)語法不是太緊要時(shí),這就是我們精力需要集中的地方——更高級的方法和函數(shù),將有助于更方便地找到解決方案。
語法和視覺化語言一起消失
雖然已經(jīng)預(yù)言很多年了,但是它在某些代碼——盡管不是全部——仍在緩慢地發(fā)生著。某些編程繼續(xù)著非常文字式,但是有些正變得更加視覺化【注4】,這意味著潛在的計(jì)算機(jī)語言不是太重要。
GUI 構(gòu)建器是最容易看到這個(gè)現(xiàn)象的地方。你可以整日整夜地拖拉用戶界面部件,而不用擔(dān)心它是 C、Java 或其它語言。細(xì)節(jié)在視覺化盒子里被編碼。
AndroidBuilder 使得拖拉更多的布局成為可能,它將忠實(shí)地編寫 XML 以及需要讓代碼運(yùn)行的 Java 小代碼。很難討論視覺化語言未來會(huì)成為什么樣子,尤其是在它們多次未能意識(shí)到該預(yù)言之后,但是當(dāng)它們成長時(shí),工具將增加更多視覺化。這意味著語言沒那么強(qiáng) 大或重要了。
代碼即法律(code is law)
計(jì)算機(jī)語言有著極大的不可知論者。它 們被設(shè)計(jì)為開放、接受和幾乎無限延展的。它們意欲做你想要的任何事情。當(dāng)然,有時(shí)候由于語法,你需要使用一些額外的字符,但是這些是很少的擊鍵。之后,它 主要是 if-then-else,再加上偶爾的聰明約束。所有這些語言將幫助你用想得到它們的方式、得到你想要的結(jié)果。如果有一些苛責(zé)的話,那么它們應(yīng)該被設(shè)計(jì) 為盡可能保持你的代碼沒有 bug,不要限制你能做的事情。
框架的威力就在這里,這就是設(shè)計(jì)師可以決定什么被允許、什么本質(zhì)上要禁止。如果 設(shè)計(jì)師不想讓某些東西發(fā)生,那么神奇的函數(shù)調(diào)用將從 API 中消失。如果設(shè)計(jì)師喜歡這種想法,那么通常會(huì)有多個(gè)函數(shù)調(diào)用以及許多支持工具。這就是哈弗法學(xué)院教授 Larry Lessig 【注5】為什么喜歡說“代碼即法律”的原因。
框架為它們所處的互聯(lián)網(wǎng)角落建立規(guī)則,一旦你選擇它們,就必須生活在規(guī)則之下。一些博客平臺(tái)鼓勵(lì)通過 Ajax 調(diào)用與其它博客鏈接。這就是你必須謹(jǐn)慎調(diào)查、聰明選擇的原因。這就是框架最終主導(dǎo)我們生活方方面面的原因,甚至包括我們不在編程的那些短暫時(shí)光。
-
注1:交叉編譯器(英語:Cross compiler)是指一個(gè)在某個(gè)系統(tǒng)平臺(tái)下可以產(chǎn)生另一個(gè)系統(tǒng)平臺(tái)的可執(zhí)行文件的編譯器。交叉編譯器在目標(biāo)系統(tǒng)平臺(tái)(開發(fā)出來的應(yīng)用程序序所運(yùn)行的平臺(tái))難以或不容易編譯時(shí)非常有用。http://zh.wikipedia.org/wiki/%E4%BA%A4%E5%8F%89%E7%B7%A8%E8%AD%AF%E5%99%A8
-
注2:位拆裂 (Bit Banging):一種利用微控制器的通用端口仿真串行接口標(biāo)準(zhǔn)(I²C、SPI 等)的技術(shù)。
-
注3:off the grid:不使用水、電、信用卡,不上社交網(wǎng)絡(luò),以避免留下記錄;愿意用自己做的東西而愿使用現(xiàn)成的。http://www.urbandictionary.com/define.php?term=off+the+grid
-
注 4:視覺化程式設(shè)計(jì)語言(Visual programming language,以下簡稱 VPL),又稱‘圖形化編程語言’、‘視覺化程式編成語言’。系使用者利用圖形化元素進(jìn)行程式設(shè)計(jì);相異于文字式程式設(shè)計(jì)。VPL 以視覺表達(dá)為基礎(chǔ),利用‘文法’或是某種‘輔助標(biāo)記’進(jìn)行圖形與文字的排列。許多 VPL 建基于‘方塊與箭頭’的概念之上,以方塊或屏幕上的物件為本體,以箭頭相連接,以直線段與弧線段代表相互之間的關(guān)系。http://zh.wikipedia.org/wiki/%E8%A6%96%E8%A6%BA%E5%8C%96%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88%E8%AA%9E%E8%A8%80
-
注5:http://en.wikipedia.org/wiki/Lawrence_Lessig#.22Code_is_law.22