Clojure 語言的設計

基於 JVM 的決定程序員

Clojure 可以吸引人的很重要一點是它是 JVM 之上的語言,這個決定很是關鍵。web

  • 首先,由於根植於 JVM 之上,而且作到了跟 Java 語言的相互調用,它能吸引不少成熟的 Java 開發者。
  • 其次,它可使用 Java 社區豐富的開源軟件,不須要從頭去構建一個社區,你能夠看到不少 Clojure 開源代碼都是簡單地包裝 Java
    的開源包,可是經過 Clojure 高度抽象簡單的語法提供更便利的使用的方式;
  • 第三,因爲 JVM 平臺自己的高度成熟和優化,clojure 的編譯器生成的 byte code 跟 Java 編譯器生成的 byte
    code 並沒有二致(不徹底是),它的性能和穩定性也能立刻獲得保證,這比從頭構建一個新平臺成本低得多。

構建於 JVM 之上,Clojure 就是一門 嚴肅 的語言,而非不少人眼中的 LISP 家族中的 玩具 語言,你學習後能夠立刻使用而且實踐。可是 Clojure 又是 LISP 方言,LISP 的神奇能力它還都保留,這樣兼具美學和實用的語言如何讓人不愛?我相信不少熟悉 Scheme 之類方言的童鞋,而且有 Java 背景的,都會對 Clojure 有相見恨晚的感受。數據庫

設計原則編程

Clojure 的設計原則能夠歸納成 5 個詞彙:簡單、專一、實用、一致和清晰。這不是我歸納的,而是《The joy of clojure》歸納的。數組

  • 簡單 : 鼓勵純函數,極簡的語法(少數 special form),我的也認爲 clojure 不能算是多範式的語言(有部分 OO
    特性),爲了支持多範式引入的複雜度,咱們在 C++ 和 Scala 身上都看到了。
  • 專一 :前綴運算符不須要去考慮優先級,也沒有什麼菱形繼承的問題,動態類型系統(有利有弊),REPL 提供的探索式編程方法(告別修改 /
    編譯 / 運行的死循環,所見即所得)。
  • 實用 :前面提到,構建在 JVM 之上,跟 Java 語言的互操做很是容易。直接調用 Java 方法,不去發明一套新的調用語法,努力規避
    Java 語言中繁瑣的地方 (doto, 箭頭宏等等)。
  • 清晰:純函數(前面提到),immutable var,immutable 數據結構,STM
    避免鎖問題。不可變減小了心智的負擔,下降了多線程編程的難度,純函數也更利於測試和調試。
  • 一致 :語法的一致性:例如 doseq 和 for 宏相似,都支持 destructring, 支持相同的 guard
    語句(when,while)。數據結構的一致性:sequence 抽象之上的各類高階函數。
  • 具體到 STM,我我的認爲這個特性在平常編程中,其實你用到的機會很少。在 web 編程裏,你的併發模型 Web Container
    已經幫你處理(tomcat,jetty),事務也是數據庫幫你處理,幾乎找不到場合去使用 STM。這個特性在作一些中間件或者底層
    framework 的時候纔可能用到。這個特性的設計上面已經提到,跟 clojure 的設計目標是緊密相關的,跟 immutable
    數據結構也是密不可分,同時它也不是沒有代價,事務歷史記錄和慢事務頻繁回滾的代價,有時候你仍是須要退回去使用 Java 那套鎖機制,慶幸的是 Clojure 不阻止你去使用,而且提供了相似 locking 這樣的宏來方便你使用。

缺陷tomcat

Clojure 的設計缺陷不能說是缺陷,這是因爲它設計的目標決定的,有得必有失。網絡

  • 首先仍是 JVM,基於 JVM 有種種好處,可是 JVM 的啓動速度實在悲劇,所以用 Clojure 寫一些小的 script
    處理平常事務,顯得仍是不夠駕輕就熟,這樣的工做我仍是用 Ruby,Python 的腳本語言來搞定更便捷。不過目前 Clojure
    有一些其餘語言之上的實現,好比 clojure-py、joxa、clojureclr 這些實現應該會比 JVM
    的啓動快不少(抱歉,我沒測試過)。 不只如此,由於 Clojure 跟 JVM 平臺的綁定如此之深,而且爲了真正發揮 Clojure
    的威力,你還須要去熟悉 Java 平臺的東西,熟悉 Java 語言、類庫、內存模型、GC
    優化、多線程和網絡編程、開源類庫等等。能夠這樣認爲:想成爲一個好的 Clojure 程序員,首先須要是一名好的 Java
    程序員。這也必定程度上阻礙了 Clojure 的推廣,提升了學習成本。
  • 其次,Clojure 的 API 設計上,有時候不符合你的直覺,而是符合 Clojure 的哲學,好比 contains? 函數對
    vector 等數組型集合的調用上。關於這一點,Rich 的回答是 Elegance and familiarity are
    orthogonal.,也就是優雅和熟悉是正交關係的。保持 API 內在的一致性,比直覺的 熟悉 更重要,這是更深刻思考、理性的直覺。
  • 第三,弱類型的好處足夠多,靈活,減小聲明代碼,適合探索式編程;一樣,壞處也不是沒有,沒有類型保障,錯誤可能要等到運行時才能發現,靜態代碼檢查工具也沒有辦法幫你發現,這就須要你必定程度的測試代碼來保證運行時行爲。
  • 第四,性能上,雖然 clojure 生成的字節碼已經很高效,也有 type hint 這樣的技術來幫助提高性能,可是會有很多的轉型
    (checkcast)、裝箱和拆箱(boxing and
    unboxing)以及類型判斷分支跳轉的多餘指令,這在一些性能敏感的應用裏可能會暴露出來。儘管我認爲大多數網站型的應用瓶頸都會落在 IO
    上。

總之, Clojure 是一門精心設計的、徹底融入做者對編程的思考的、富有生產力的現代編程語言,值得每一個對生產效率、函數式編程、併發編程有興趣的朋友深刻了解下。數據結構

相關文章
相關標籤/搜索