Saturday, January 29, 2022

我的 Clojure 學習之路

我在想,如果分享一下,我學習 Clojure 的數個階段,說不定其它想要學 Clojure 的人也會覺得參考我的學習之路有點用處?

我大概把自己的程度,分成下列的四個階段。

  1. Before knowing Clojure
  2. Clojure Basic 
  3. Tried a lot of libraries  
  4. Selected Libraries 

階段 1:  < Before knowing Clojure >

在我使用 Clojure 之前,我就已經使用過許多不同的程式語言:C/C++, PHP, Shell Script, Java, JavaScript, Python, Golang。此外,函數式程式設計大概也有一定的基礎。依賴注入的問題,也算是有常在思考了。只是,我從來沒有想到過,寫程式時產生的 90% 的困惑,都可以在一個語言裡直接找到解答。

階段 2: < 學習 Clojure 的 Basic >

這個階段,主要是做了四件事:

  1. 寫了不少的 4clojure 的練習題
  2. 看了 Clojure for Brave and True
  3. 搞定了 Editor integration 
  4. 開發了一個 Clojure web application ,但是,前端還是用 javascript 。

階段 3: < Tried a lot of libraries >

在這個階段,我為了想要更精進,積極地使用各種 libraries 。其實我曾經看過 Rich Hickey 談過一個概念,「想要成為高手,應該要選擇一個 domain problem ,深入研究,然後,透過了解問題、解決問題、透徹地思考,從而成為真正的高手。」不過,Rich Hickey 的教誨,我把它先放一邊,我認為,那個建議是給『接近他那個水準的人使用的』,我的話,先追求廣度就好。

於是,在這個階段,我嘗試了:

  1. Datomic
  2. ClojureScript
  3. Tachyons CSS (這個不是 Clojure ,但是,是 Clojure 社群的人推荐我學的。)

這個時期,我開發 web application ,依然主要使用 Luminus 。

階段 4: < Selected Libraries >

因為在 Gaiwan 工作的關系,我使用的 libraries 會有老闆的建議。( 還是說,是規定?) 總之,這個時期我相當幸運,在 Gaiwan 工作,雖然說,工作本身並不簡單:開發工作總是有時程的壓力,而且常常要學新的 libraries 。但是,有任何疑問,隨時可以問 Arne Brasseur 。

總之,在這個階段訓練了一陣子之後,我學到了幾件重要的事:

1. 開發軟體,要先搞定 walking skeleton 

2. 有一些太複雜的 domain problem ,如果覺得開發複雜的 API library ,自己日後還是會用得很痛苦的話,可能要考慮,把 API library 做成 hiccup DSL ,然後使用 tree walk interpreter 

3. 有一些 java interoperation 的問題,如果程式很難寫,可能要考慮「剝皮接枝法

經過了這個階段的訓練,我發現自己開發 web application ,開始不想依賴 Luminus 了。依賴 Luminus 真的很省事,很多困難的 technical decision 都讓 Luminus 的作者幫我決定就好。但是,我已經學過夠多的東西了,這些決定我可以自己做了。 


如果剛好是程度處於我上文階段 2 或是 3 的朋友,這邊有一些我整理出來的連結。


如果已經想要走入階段 4 的朋友,這邊有 LambdaIsland recommended Clojure libraries
- Dependency management: Clojure CLI (avoid lein or boot)
- System configuration: Aero
- System state management: Integrant (avoid component)
- Routing: Reitit
- HTTP Server: conservative choice is Jetty. Strongest contenders are
Immutant-web and Aleph. We're keeping a close eye on Pohjavirta (avoid
http-kit)
- Relational Database Access: next-jdbc + honeysql
- Testing: clojure.test + Kaocha
- Editor: Corgi (formerly lesser-evil) or VS Code + Calva
- Datalog databases: conservative choice is still Datomic, keeping a close eye
on Crux, Asami, Datahike, Datalevin
- Schema validation: Malli (alternatively stick to Spec 1, but with spec being
eternally in alpha it seems wise to hold off)
- ClojureScript tooling: figwheel-main or shadow-cljs
- URI: lambdaisland/uri
- Http Request: hato at the backend, and lambdaisland/fetch at the frontend.
- Time: java.time at the backend, and lambdaisland/deja-fu at the frontend
- Log: SLF4J + Logback + pedestal.log at the backend, and lambdisland/glogi at the frontend.

另一個很值得參考的 libraries list ,則是 JUXT 的 Clojure Radar 。 Radar 列了很多的項目。
比方說:
- ClojureScript interactive tool: Devcards
- Database migration Tooling:  Ragtime