我只會Java一門語言夠用嗎?
我只會 Java 一門語言夠用嗎?
- 面向對象用來組織程序是好,但我用C
- 我用C++,函數式編程的好,跟我有什么關系
- 動態語言那些特性很好,可惜我用Java
- ……
如果你這么想,說明你被自己的看家本事給局限住了,這種思維方式會讓你即便學到了更多好東西,也無可奈何。
程序設計語言之間沒那么涇渭分明,多學幾門才能打破語言局限,讓設計更好落地。可根據項目特點選擇合適語言,也可以將其它語言一些優秀的地方借鑒過來。Andrew Hunt和David Thomas在《程序員修煉之道》(The Pragmatic Programmer)中給程序員們提了一項重要的建議:每年至少學習一門新語言。
語言那么多,我要一個一個都學過去嗎?學語言到底在學啥?
程序設計語言本身也是一個軟件,它也包含模型、接口和實現。學習程序設計語言主要是為了學習程序設計語言提供的編程模型,比如:不同的程序組織方式,不同的控制結構等等。不同編程模型會帶給你不同思考方式。
1 程序設計語言發展簡史
程序設計語言都是圖靈完備:語言指定的數據操作規則能夠實現圖靈機的全部功能。圖靈機是所有程序設計語言最底層的模型,程序設計語言都是在這個基礎上生長,包括計算機用0、1編碼。
計算機能夠識別的都是0、1,但用0、1寫代碼太麻煩。所以,計算機誕生之初,就產生匯編語言,將那些0101操作符變成更容易記住的ADD、MOV等指令。
后來發現匯編寫程序也痛苦,只有對計算機了如指掌,才能寫好匯編。即便你熟練掌握一種計算機的匯編語言,換成另外一種計算機,也得從頭學。
高級程序設計語言登場。
第一門高級程序設計語言Fortran,為程序設計語言的發展奠定基礎。數據開始擁有類型(類型就是一種對內存數據的解釋方式)。人們逐漸認識到高級程序設計語言對開發效率提高。
早期程序設計語言探索的集大成者就是C,它提供對計算機而言最恰當抽象,屏蔽了計算機硬件諸多細節。隨高級程序設計語言發展,門檻逐步降低,可開發的程序規模膨脹。搭著C語言的便車將面向對象的程序設計風格成為主流,即C++。
各種高級程序設計語言已屏蔽很多細節,但內存管理始終沒有得到很好解決。人們早就在嘗試各種屏蔽內存管理的方式,但因早期計算機硬件性能有限,沒有一種成為行業主流。
后來,計算機硬件能力得到大幅提升,這讓那些在故紙堆里的技術又煥發了新的活力。該階段勝者Java,一方面,支持面向對象編程;還有垃圾回收機制——一種內存管理的方式。
Java之路也很坎坷,因為它早期在個人電腦上的嘗試并不算成功。后來選擇了企業級開發的賽道,才有機會展現自己的優勢。因為企業級服務器本身性能優于個人電腦,對Java有更高的容忍度,它才得到了機會,不斷進行自身的優化。
當硬件不再是程序設計語言的發展障礙之后,程序設計語言又該如何發展呢?
從前面的歷程不難看出,程序設計語言的發展就是一個“逐步遠離計算機硬件,向著待解決的問題靠近”的過程。所以,程序設計語言接下來的發展方向就是探索怎么更好地解決問題了。
前面說的這些只是程序設計語言發展的主流路徑。
還有一條不那么主流的路徑也一直在發展,就是函數式編程的程序設計語言,這方面的代表就是LISP。在這條路上,剛開始,很多人都是偏學術風格的,關心解決方案是否優雅,也就是說,如何解決問題,如何一層層構建抽象。也探索更多可能,垃圾回收機制就是從這里來的。但同樣受限于當時硬件的性能,這條路上的探索在很長一段時間之內都只是一個小眾游戲。
當硬件的性能不再成為阻礙,如何解決問題開始變得越來越重要時,函數式編程終于和程序設計語言發展的主流匯合了。促進函數式編程引起廣泛重視也還有一個硬件因素:多核。
多核的出現,本身是IT行業應對CPU發展進入瓶頸期的一個解決方案,但它卻打破了很多程序員只習慣于利用一個CPU寫程序的傳統方式。
為了利用多核的優勢,人們探索了各種方案,今天看到的各種并發模型、異步模型等解決方案都從那時開始得到了蓬勃的發展。函數式編程在這個方面的探索就是利用自己聲明式的表達方式屏蔽了硬件差異。讓人們注意到函數式編程的價值的就是著名的MapReduce。
函數式編程興起,讓那些在函數式編程社區的探索隨之興起,比如,聲明式編程、DSL、元編程等等。一些后出現的程序設計語言開始將面向對象和函數式編程二者融合起來,比如Scala。而像Java和C++這些“老戰士”則逐漸地將函數式編程的支持加入到語言之中。
相比于這些“正規軍”,還有一股力量也逐漸從邊緣走上了舞臺,這就是動態語言,代表語言有 Perl、Python、Ruby、PHP等等。以前,人們更喜歡用“腳本語言”稱呼這類程序設計語言,這個名字表明,它就是為了簡單地解決一些特定的問題而出現的。所以,在人們心目中,它們顯得并不那么正式。但它們簡單、輕巧的特性有效地降低了入門的門檻,也贏得了一大批擁躉。
語言的發展就是一個互相學習和借鑒的過程。以前,動態語言的弱項在于不適用于規模比較大的工程,而近些年來,隨著動態語言用戶的增多,配套的工具也逐漸多了起來,動態語言項目的規模也逐漸增大。而在主航道的程序設計語言,也紛紛向動態語言學習,努力地簡化代碼編寫的難度,比如,Java和C++都開始支持類型推演(Type Inference),目的就是讓程序員少敲幾個字符。
把程序設計語言當作一個軟件,它的發展歷程就是一個逐漸添加新模型的過程,而其發展的結果就是如今的開發門檻越來越低,能夠開發的程序規模越來越大。
2 語法都是語法糖
C語言提供了對匯編指令直接的封裝。C++先是提供了面向對象,后來又提供了泛型編程。Java把內存管理從開發者面前去掉了,后來引入的Annotation可以進行聲明式編程。Ruby提供了動態類型,以及由Ruby on Rails引導出的DSL風格。Scala和Clojure提供了函數式編程。Rust提供了新的內存管理方式,而Libra提供的Move語言則把它進一步抽象成了資源的概念。既然學習新的程序設計語言是為了學習新的編程模型,反過來也可以說,不提供新編程模型的語言是不值得刻意學習的。如果你已經學會了一兩門程序設計語言,學習一門新的語言其實并不困難,因為每種語言提供的新模型是有限的,基本的元素類似,無非用不同關鍵字。
所以,學習新語言,只是在做增量的學習,思維負擔并沒那么沉重。一旦對于程序設計語言的模型有了新的認識,你就能理解一件事:一切語法都是語法糖。
語法糖(Syntactic sugar)是英國計算機科學家彼得·蘭丁發明的一個術語,指的是那些為了方便程序員使用的語法,它對語言的功能沒有影響。
懂得了語法糖的道理,要想更好地理解程序設計語言,一種好的做法就是打開語法糖,了解一下語法是怎么實現的:
類型是一種對內存的解釋方式。class/struct是把有相關性的數據存放到一起的一種數據組織方式。Groovy、Scala、Kotlin、Clojure等JVM上的新語言,提供了一種不同于Java的封裝JVM的方式。……
3 總結
語言的發展并非一蹴而就,而是一個漸進式的發展歷程。一些新的嘗試總會在一些不起眼的地方冒出來,而且語言之間也在相互借鑒。
如果你能每年學習一門新語言,起初,你可以了解不同的編程模型。當你的積累足夠多了,學習語言就是在跟蹤程序設計語言的最新發展了。
當你手里有了足夠多的“武器”時,你就可以打開思路,運用不同的方式解決問題了,甚至把其它語言的好東西,借鑒到自己使用的語言中。
學習不同的程序設計語言可以幫助我們更好地落地設計,也可以讓我們向不同的語言借鑒優秀的方面。
我們簡要地了解了程序設計語言的發展歷史,從最開始的對機器模型的封裝,到今天不斷降低的開發門檻,程序設計語言的演化從未停止。我們也看到各種不同的編程風格在經歷了最初各自獨立的發展之后,開始慢慢融合。
對程序設計語言發展的了解,可以幫助我們理解一件事:一切語法都是語法糖。新的語法通常是在既有的結構上不斷添加出來的,為的是簡化代碼的編寫。
《程序員修煉之道》鼓勵程序員們每年至少學習一門新語言,主要是為了讓我們去學習新的編程模型,而不提供新編程模型的語言不值得刻意去學習。
不過,這就需要你對程序設計語言有著更深的理解。
本文轉載自微信公眾號「 JavaEdge」,作者「 JavaEdge」,可以通過以下二維碼關注。
轉載本文請聯系「 JavaEdge」公眾號。