Clojure 用後感

最後接手了一個項目,主要是 Java,但使用了 Clojure 做爲規則引擎的腳本語言。簡而言之就是把一些邏輯實現用 Clojure 實現,而後放到數據庫裏,Java 在用到時就動態加載編譯執行。java

之因此用 Clojure 也只是由於當年 Function Language 正是熱點,因此在選型時項目負責人就把 Imperative Language,例如 JavaScript, Python 之類的排除在外了,在 FL 中的選擇主要就是 Scala 和 Clojure 選誰的問題,畢竟其它的像是 LISP 或 ErLang 之類的怎麼和 JVM 集成是個大問題。Clojure 由於號稱想比 Scala 是更加純粹的 FL 因此最終入選。因此如今看來,其實做所謂的戰略決策時基本上是憑運氣,在這個所謂的歷史關口做出的選擇成了如今全部接手人員的噩夢。沒有人懂 Clojure,原先的人都已經跑路了,新人也沒有人願意學 Clojure,沒辦法,程序員其實也是很功利的,若是學英語你們都花錢去學,要是學拉丁語,極可能就是倒貼錢也沒人學。若是當年選的是 Scala,或者是 Python,那如今的人可就會對當年的高瞻遠矚佩服到五體投地。其實都是賭,有人賭對了,有人賭錯了而已。如今一個項目正在大肆使用 Python,說實話我挺擔憂。若是是純粹的 Python 項目也還好,壞就壞在它也是用 Python 做會腳本引擎。天知道選錯了又是啥後果。以我接手的這個項目爲例,已經超過10年的歷史,裏面除了 Java 和 Clojure,還混雜着 Scala 和其它一些語言寫的模塊,尤爲是其中一個模塊用的語言竟然是公司本身開發的,然而這個語言的項目組已經解散再也不維護了,更奇葩是的這個語言竟然跟 JDK 的某些版本不兼容,導制在升級 JDK 這種無害操做時心驚膽顫。程序員

 在這裏我忍不住吐槽下 Java,你們能夠看到之前面的選項中,歷來沒有出現過 Java,從沒試圖直接用 Java 做爲腳本引擎。其實做爲一個 Java 項目,就用本身做腳本引擎不是最好嗎?但 Java 不知是否是腦子進水了,自廢武功。之前 Java 還真能夠,在 JDK 1.4 的時候,我還曾經在項目中使用過,即時編譯 Java 腳本執行。固然 Java 仍然有個缺陷是這個腳本是不支持熱部署的,也就是說你改了你的腳本,只能重啓應用才能讓它生效。由於 Java 並不支持手工 Unload 指定的類。但不管如何,有的用總比沒的用強,並且這些規則腳本並不會頻繁修改。但到了某個版本後,多是 1.6,這個動態編譯的功能被從 JRE 中去掉了,改放到了 JDK 的一個附加包中,這可就要命了,由於不少服務器上是不安裝完整 JDK 的,再後來好像直接從 JDK 中拿掉了,你想動態加載得本身用 java 命令去編譯……真是謝謝你全家。數據庫

好了,吐槽結束,迴歸 Clojure 自己,其實仍是吐槽。編程

 1. Clojure 很容易寫成攤大餅式的代碼,簡單來說就是函數執行的結果直接當成下一個函數的輸入,並且嵌套至無窮,若是有人在 Java 裏這樣寫必定會被人罵死。就如同一個笑語說的,某間諜偷到了某核心系統源代碼的最後一頁——整整一頁的右括號,由於系統是 Clojure 寫的。其實 Clojure 寫的代碼也能夠更好看一些,但不知道爲啥,彷佛大部分寫 Clojure 的人都巴不得把所有功能都在一行裏實現,即所謂的簡練,能用一行代碼實現 Java 的一大片代碼。其實代碼簡練與否不是靠行數的,而是靠邏輯行數,若是你把 Clojure 的每一個函數調用都新起一行,左右括號也新起一行,那行數就與 Java 差很少。不然 Java 也大能夠把換行符都去掉宣稱本身也只有一行。服務器

2. 代碼攤大餅也罷了,執行順序仍是由裏向外, 這個就要了命了。正常的閱讀習慣是從左向右,從上向下,你搞個從裏向外實在是不知所謂。有人說那是你不習慣,習慣了就好。但問題是爲啥你的習慣與你們都不同。就像別人的書都是左右排版,你不但搞個上下排版,並且仍是從下往上排,你說別人難不難過。編程語言

3. 哦,對了,有人說 FL 對編譯器友好,問題是我是作應用的,不是作編譯器的,我只知道它對我很不友好。ide

4. 有人說這對程序員也很友好,例如 2 + 5 * 3 + 4 * 6, 你若是不用 FL 就得熟知各類操做符優先級。但問題是經常使用的操做符優先級我在小學就學過了,而你卻是不用記操做符優先級了,(+ 2 (+ (* 5 3) (* 4 6))) 這種寫法看起來很舒服?你要看懂,是否是還得先在紙上翻譯成正常的順序才能明白?知道你們輸入中文爲啥用拼音不用五筆不?真不是拼音比五筆好學,而是拼音你們已經都學會了。函數

5. Clojure 程序裏充斥着各類特殊符號,例如 #() 表示快速函數聲明, #{} 表示快速 hash-map 聲明,-> 表示參數首位順序執行, ->> 表示參數末位順序執行……哦,對了,這又被看作 Clojure 的優勢,讓程序簡練優美。就算你們沒讀過信息論,能不能想一想爲啥大多數編程語言都不這麼幹?由於冗餘信息的一大用處就是提升辯識度,也就是可讀性。若是真追求簡練,那應該填接用機器碼編程,只用 0 和 1 就夠了。翻譯

6. 號稱一切函數都要有返回值,然而就像常言說的,凡事無絕對,我就是想打個 log 須要啥返回值。因此返回 nil 也算有返回值?對象

7. 宣稱一切函數都沒有反作用,由於全部的 Clojure 對象都是不可變對象,這意味着一個對象在處理過程當中會不停地生成它的硬拷貝來保證這一點,固然它又宣稱它使用了很高明的技術來保證只複製須要複製的部分以免把內存撐爆……好吧,我除了選擇相信還能說啥呢。

相關文章
相關標籤/搜索