鮑勃大爺:為何選擇Clojure?
我用許多不同的語言編寫了系統; 從彙編程式到Java。我用二進位制機器語言編寫程式。我用Fortran,COBOL,PL / 1,C,Pascal,C ++,Java,Lua,Smalltalk,Logo和其他幾十種語言編寫了應用程式。我使用了靜態型別語言,有很多型別推斷。我用過無型別語言。我使用了動態型別語言。我使用了像Forth這樣的基於堆疊的語言,以及像Prolog這樣的基於邏輯的語言。
在過去的五十年裡,我使用了很多不同的語言。(應該改稱鮑勃大爺)
我得出了一個結論。
我最喜歡的語言是Lisp, 我認為這種語言將比其他語言更耐用,我相信這種語言最終將成為所有程式設計師使用的標準語言......
我不是Lisp的粉絲。40年來,我不是Lisp的粉絲。我看到CARs和CDRs和CADDADDRs,並認為這只是學術上的胡扯; 有趣但不是真正有用。
然後,十年前我找到了SICP。之後我找到了Clojure。Clojure是一個Lisp,它位於Java生態系統之上(並且沒有CARs或CDRs或CADADAADRs)。
我沒有立刻相信Clojure。花了幾年時間。但是在經常磕磕絆絆和沮喪之後,我開始意識到這種語言是我用過的最簡單,最優雅,最不那麼強大的語言 - 而且不是很小。
那麼,為什麼這麼看好Clojure?我已經列了一份清單。你準備好了嗎?
1. 表達經濟
如果您想知道這份清單列表的其餘部分在哪裡,那是存在的,這就是原因,只有一個。
在Clojure中編寫富有表現力的程式碼更簡單,更容易,更少遮擋。它需要更少的行。它需要更少的字元。它需要更少的時間。它需要較少的心理體操。
為什麼會這樣?答案很簡單。的確答案是:非常簡單。
該語言幾乎沒有語法或語法。
解釋這一點的最佳方法可能是向您展示一個例子。所以,在這裡,為了您的娛樂,是列印前25個整數方塊的程式:
(println (take 25 (map #(* % %) (range)))) |
我們來看看這裡的語法:
- ( 意思是:開始一個list。
- ) 意思是:list結束。
- 名稱就是名稱,在這種情況下都是函式。
- * 是乘法函式的名稱。
- # 表示:將下一個list解釋為函式。
- % 意思是:該函式的第一個引數。
你剛剛看到Clojure語法的80%左右。
首先是那個“(”符號。這意味著它與“)” 之間的所有內容都是一個list。在大多數情況下,Clojure將list解釋為函式呼叫。在這種情況下,函式是println。這只是類似我們習慣用Java 的System.out.println。
我們傳遞的是println什麼?我們傳遞了take函式的結果。該take函式需要兩個引數。第一個25是take的專案數;第二個引數是一個list。因此,這個take函式將返回一個list,其中包含第二個引數中list的前25項。
第二個引數中的list是什麼?這是呼叫map函式的結果。該map函式需要兩個引數。第一個是函式,第二個是list。該map函式將返回一個list,該list是在傳入list的每個元素上呼叫傳入函式的結果。
傳入map的函式是什麼?它是由建立的匿名函式,它只是簡單地呼叫它複製的第一個引數,這是%的意思。
什麼list被傳入map?它是透過呼叫range函式返回的list,該range函式只返回“所有”非負整數的list列表。該列表是惰性的,因此實際上只會生成上游函式所需的整數。
有些人不喜歡%語法的複雜性,所以我們可以建立一個square函式如下:
(defn square [x] (* x x)) (println (take 25 (map square (range)))) |
defn定義了一個名為square新函式,括號[]定義了一種稱為向量的不同型別的“list列表”。list列表具有連結列表的執行時複雜性。向量具有陣列的執行時複雜性。無論如何,在這種情況下,向量告訴defn該square函式需要一個名為的引數x。其餘你應該能夠推斷出來。
這使第二行更好一些理解。該map函式只是呼叫square。
現在你已經看到了Clojure大約90%的語法。
現在讓我們將它與等效的Java程式進行比較:
public class SquaresOfIntegers { public static void main(String[] args) { for (int i=0; i<25; i++) System.out.println(i*i); } } |
(banq注:被Java洗腦的我一眼看到這份程式碼,頓然一目瞭然,一下子明白了,Clojure表達的那麼擰巴,Clojure和Java大概是文言文和白話文的區別,文言文確實很簡單,讀懂文言文的人惜字如金)
即使你不計算封閉的類,這也更加冗長。然而,更重要的是,這涵蓋了大約5%的Java語法。並且不要讓我開始與C ++進行比較。
現在我不想說明這一點。經過與語言之後的語言比較,我可以繼續比較。底線是Clojure的語法比大多數語言小得多。這種最小的語法意味著我能夠比大多數其他語言更清楚,更直接地表達問題。
看,我很難啊。我當時是一名C ++程式設計師。更重要的是,我(不再是)是一名C ++語言律師。我沉迷於該語言的重量級語法。我被所有可愛的“fidelty bits”迷住了。二十年前,我發現向Java過渡到相當“meh”。它只是一個精簡的C ++(它之後變得更加肥胖)。
但是我向Clojure的過渡令人大開眼界。基於輕量級語法,我希望它適用於一些課堂練習,但不適用於構建大型系統。在我看來,大型系統等同於大型語法。孩子,我錯了。
相反,我發現Clojure的最小語法比Java或C ++的更重的語法更有利於構建大型系統。事實上,這不是一場競賽。構建大型系統是Clojure比我使用的任何其他語言更簡單,更容易。
正如我在開始時指出的那樣,我使用了很多語言。
但是關於…?
所以你可能有一些抱怨,問題,異議等等。讓我看看我是否可以預料到它們:
我的天啊!所有這些括號
你幾歲啊…?睜開大眼看看,這是一個java函式呼叫:f(x)。現在這裡是Clojure中相應的函式呼叫:(f x)。你在那裡看到任何額外的括號嗎?
好的,嘻嘻,這不完全公平。我們最後會看到一些括號,但那只是因為我們傾向於巢狀函式呼叫。看看上面的整數程式,你會明白為什麼。不要擔心,如果你真的不喜歡那種巢狀語法,你總是可以使用執行緒宏(讓讀者理解)。
但是不是很慢嗎?
不,Clojure並不慢。哦,看,它不是C.它不是彙編程式。如果納秒是您的關注,那麼您可能不希望Clojure在您最內層的迴圈中。您可能也不想要Java或C#。但是我們現在編寫的99.9%的軟體不需要納秒效能。我使用Clojure 構建了一個基於GUI的實時動畫太空戰遊戲。即使螢幕上有數百個物體,我也可以將幀速率保持在20s 。Clojure並不慢。
但是Javascript怎麼樣?
ClojureScript編譯到Javascript並在瀏覽器中執行就好了。實際上,我上面提到的太空戰計劃是使用ClojureScript編譯的,並且在瀏覽器中以比本機模式更高的幀率執行(我還在試圖解決這個問題。)
但它是動態型別的!
動態型別必須寫測試,不是嗎?作為測試的一部分,您可以使用clojure/spec庫來指定型別的模式,並使用前置條件和後置條件(按合同樣式設計)進行動態檢查,讓您心滿意足。
但它是動態型別的[2] !!
型別宣告是需要語法成本的。而語法成本的加入會降低表達的經濟性。
但是,Dammit,它是動態型別的!
好的我明白了。你喜歡靜態型別。很好,你可以使用一個很好的靜態型別語言,我將使用Clojure。我們之前還在蘇格蘭呢。
那IDE呢?
帶有Cursive外掛的IntelliJ非常好用。大多數Clojure程式設計師使用Emacs。
重構怎麼樣?
帶有Cursive的IntelliJ有一些很好的重構; 雖然他們還沒有“提取方法”(來吧夥計!)
Java互操作怎麼樣?
沒問題。Clojure程式可以直接呼叫Java。Java程式只需要一點點修改就可以呼叫Clojure程式。Interop不應該是您關注的問題。
我在哪裡可以找到Clojure程式設計師?
他們在那裡; 但你最好還是編寫它們。語法很簡單。您可能已經知道Java平臺。只需決定在Clojure中構建您的下一個系統。花一兩個星期習慣這門語言。然後開始哦,當你在幾個月的時間裡,你會意識到你早期的東西是多麼原始,你會被誘惑去清理它。但還有什麼是新的?
但是那是一種新語言.
是的,每個月都有新的語言。每週。每天。我們不乏新語言。關於這些新語言的事情是,任何一種語言都沒有新的東西。它們只是由他們在一個罐子裡切割和震動的舊語言組成,然後在Yahtzee的語言遊戲中拋棄。
好的,那不完全公平。在語言空間中仍有一些好的想法滲透。但這些想法都不是革命性的。我們進入了“調整”的時代。我沒有發現任何新語言幾乎與Clojure一樣引人注目,僅僅因為幾乎所有語言都具有額外的語法。
其他語言的語法也很少。為什麼不能成為選擇之一?
是的,這是真的。Forth有一個很小的語法。Smalltalk也是如此。但是這兩種語言都有自己的包袱。Forth是一種字尾表示式(將運算子寫在運算元之後) 語言。Forth的短語並不是表達經濟。雖然我發現基於它的PostScript很有趣。
Smalltalk小而優雅,美麗。它催生了設計模式革命。它催生了重構革命。它催生了TDD革命。它有助於產生敏捷革命。Smalltalk是一種具有巨大影響力的語言。
Smalltalk也是一種基於影像的語言。很少有程式設計師能夠將自己的想法包含在真正意義上的內容中。不幸的是,與所有基於文字檔案的語言相比,語言萎縮了。
到目前為止,Lisp比Smalltalk或Forth更老。它建立於1957年,源自30年代的概念,並且從未像Smalltalk和Forth那樣萎靡不振。的確,這是拒絕死亡的語言。我們試圖殺了很多次。但就像令人討厭的鄰居流浪貓一樣,它會......繼續......回來。
最後,Lisp功能齊全。未來看起來非常實用。
相關文章
- 鮑勃大爺:SOLID概念解釋Solid
- 鮑勃大爺:單元測試中單元是多小?
- 鮑勃大叔為敏捷正名敏捷
- 鮑勃大爺:將if/else中每個條件變為邏輯並列互拆而不依賴執行順序。
- 為什麼Dark不選擇Rust/Clojure/Haskell/Scala? - darklangRustHaskell
- 鮑勃大爺:敏捷是讓經理面對慘淡的現實!是不是這種試錯成本太高?敏捷
- 為何選擇Spring Boot?Spring Boot
- 鮑勃大爺:物件是更關注行為,資料庫表則是簡單的資料結構,if/else/switch有使用依據物件資料庫資料結構
- 鮑勃大爺:軟體架構類似房子,物件導向是房子的結構,水管線管是函數語言程式設計架構物件函數程式設計
- 拜託:不要像鮑勃大叔那樣重構
- 為何選擇阿里雲 簡訊服務阿里
- 為什麼我不推薦鮑勃叔叔的清晰架構這本書?架構
- 飛書,為何成為國內大模型獨角獸們的共同選擇?大模型
- 何時選擇敏捷?敏捷
- 鮑勃大叔:程式設計正規化並不排斥!程式設計
- IT/網際網路為何會成為大學生求職的第一選擇?求職
- 鮑勃大叔:是否有些語言不需要設計模式?設計模式
- ORM是不適合DDD的!鮑勃大叔表示同意ORM
- 我們為何選擇 Cilium 作為 Kubernetes 的網路介面
- 鮑勃大爺:“如果您不喜歡結對程式設計,就不要結對, 但是要做好準備讓那些已經使用配對技巧的人飛越您。”程式設計
- 鮑勃大叔:SOLID原則適合函式程式設計嗎?Solid函式程式設計
- 你還在用if-else嗎?鮑勃大叔提出改進意見!
- 為何選擇Spring AI Alibaba開發智慧客服平臺?SpringAI
- 遊戲開發者為何選擇Apple Arcade平臺?遊戲開發APP
- 企業資料為何要選擇企業雲盤
- 為何選擇合適的文件管理系統至關重要?
- 《王牌戰士》為何選擇日式熱血漫的畫風?
- 企業為何紛紛選擇CRM客戶管理系統
- 探索分散式服務框架Dubbo3:為何選擇Dubbo分散式框架
- 鮑勃大爺調查提問:兩者哪個更昂貴?A.在程式碼中新增難以更改的功能。B.保持程式碼足夠靈活性以輕鬆新增新功能。
- 盤點爬蟲語言為何大多選擇Python而不是Java爬蟲PythonJava
- 為何Symless選擇Rust,而不是Go、C++或Node.js?RustGoC++Node.js
- Vue為何棄用經典的Ajax,選擇新技術Axios?VueiOS
- Python發展前景如何?人工智慧為何選擇Python語言?Python人工智慧
- 鮑勃大叔是一個從未交付過軟體的欺詐者? - Nico
- 鮑勃大叔:走得快的唯一方法就是好好地走
- 為何Node.js 能成為 Web 應用開發最佳選擇?【強推理由】Node.jsWeb
- 大量海歸來搶工作了!圖解大資料:為何80%留學生選擇回國圖解大資料