後記(Afterword)#
本後記由 Gina Martiny 撰寫——她是 Bob 大叔(Robert C. Martin)的女兒,目前任職於 Clean Coders Studio。她原本是化工工程師,2020 年起轉入軟體開發。
「你最愛的 stack 是什麼」#
2022 年 3 月,Gina 在朋友的生日派對上偶遇兩位開發者,被問到一個讓她當場大腦狂轉的問題——
「So, what’s your preferred stack?」
最後她不太有自信地答出:「Clojure?」
對方驚訝地反問:「真的嗎?整個 stack 都用?前端、後端都用 Clojure?我從沒聽過。它不是 Lisp 嗎?是函式式吧?怎麼運作?」
如果你讀到這裡,本書的前面章節已經給了比 Gina 當下能給的更完整的解釋。
Gina 的背景:化工工程師到軟體開發者#
派對的 11 年前,Gina 在伊利諾伊州 Metropolis 開始她的化工工程師生涯,學習鈾六氟化物(uranium hexafluoride)的製程。十年間她做到化工製造廠的生產領導,學到很多關於:
- 流程
- 狀態
- 人
- 企業文化
- 她當時無法修復的「破碎流程」
2020 年的疫情與一場家庭學徒制#
2020 年 3 月疫情爆發、全球停擺。整整八週,她身邊有一個人——既擁有她欠缺的能力,也親自制定了「掌握那些能力的法則」。
於是她問爸爸(Bob 大叔):「我要學到多深,才能修好那些我急著想修的問題?」
那晚 Bob 給她看自己當時的副業專案:用 Clojure 自動產生「COVID-19 各郡感染與死亡圖表」。Gina 不認得語法,於是 Bob 介紹了 Clojure:
- OO 程序式 vs. 函式式語言的差別
- 為什麼函式式較安全、複雜度較低
- 用一個與第 15 章「Bob 與 Alice 通電話」幾乎一模一樣的 race condition 來說明
接著父女合寫程式——Gina 寫了幾個簡單的算術函式(先寫測試,當然)。Bob 帶她認識 Quil,並說明它如何透過「每次迭代以新狀態 recur」來避免修改狀態。
那晚寫的原始碼列印本,至今仍在 Gina 案頭——她寫這篇後記時,那份手稿就放在面前。
一年後,她從軟體學徒「畢業」,成為 Clean Coders Studio 的全職開發者。
為什麼那個「stack 問題」是顆炸彈#
到 2022 年 3 月:
- Gina 進軟體業還很新
- 疫情導致大型聚會稀少
- 巴頓魯日(Baton Rouge)軟體產業還在成長期,社群曝光有限
那場生日派對是她第一次與 Clean Coders 之外的開發者面對面交流——她有足夠的知識翻譯與拼湊出問題的意思,但還沒有自信自己拼齊了所有碎片。
Gina 的兩個 Clojure 小心得#
1. 跨平台共用程式碼讓她對 Clojure 真正驚艷#
當時專案的情境:
- 前端 Angular、後端 Java(部分還在從 legacy 遷移到 Clojure)
- 同一個方法常常要在 Angular、Java、有時還有 Clojure 各寫一遍——重複工作無所不在
後來客戶要求一個行動 App,功能完全與既有 Clojure 端對齊。
解法:把核心邏輯抽到一個
.cljc函式庫——Clojure 與 ClojureScript 共用的程式碼。結果:幾乎沒有任何重複實作或重寫——行動 App(ClojureScript)與後端(Clojure)共用相同的、同步測試過的程式碼。
還有什麼語言能做到「後端與多個前端都跑在同一份同步測試的程式碼上」?
2. Clojure 的 for 不是迴圈#
從 OO 過來的人很容易踩這個雷:Clojure 的
for不是迴圈。它是 list comprehension macro,不會強制副作用。
想要產生副作用的「迴圈」,請改用
doseq——它回傳nil,但會做你想做的事。
;; for: 產生新 sequence (lazy)
(for [x [1 2 3]]
(println x))
;; => 不會印出任何東西(除非有人消費這個 lazy seq)
;; doseq: 真正執行副作用
(doseq [x [1 2 3]]
(println x))
;; => 1 2 3Good luck!
——Gina Martiny, Clean Coders