FP 在應用程式的高峰可能在 2013~2014 左右,那時 John Carmack port Wolf3D 到 Haskell 上,還提到:
I haven't done any functional programming since I started crunching at Oculus, but I consider the time I spent on it extremely worthwhile.
也說過:
I feel a touch of impostor syndrome when I get invited to speak at functional programming conferences.
同年 (2014) audreyt 在 FLOLAC'14 給了演講《函數程式設計的商業應用》。
即使到了 2024 年, John Carmack 還在講:
When I started internalizing the benefits of functional programming at the design level, it was notable how many large chunks of code could be pushed behind a purely functional interface, even when implemented in a very imperative style, if you made a little effort.
根據在 web 圈打滾的經驗,什麼 Yoneda lemma, Monad, Comonad 都不重要。光是用 ADT 拆分問題、把資料結構的產生和消化配對起來,就能簡化很多程式碼。把 I/O 拆出來也能減少自己的認知負擔。
但就是會遇到那種喜歡打穿抽象、追求快還要更快的 programmer 。他可能不用開會、不用一邊工作一邊處理雜務,所以降低心智負擔的工程方法對他來說幫助不大。他可以大聲質疑別人搭建的抽象,再打穿它們好表現自己很聰明。
見過的例子有:
- 不管怎樣拿到 DOM reference 直接改就對了
- 明明 culling 應該是 framework 該考慮的事,他卻覺得自己來比較快,還只做一半
- 設計之初倚賴 event bubbling ,是為了未來可以把重效率的 canvas app 和 DOM 部分拆開,他卻引進一個 global event system 把東西焊在一起
- 在 functional programming paradigm 的 React 裡面塞個 singleton class instance
大聰明。
社群部分也沒有太好, React 圈圈一開始因為 Clojure 圈的 Om 還有所謂的 time travel debugging 而聲名大噪(此前有 Bret Victor 以 Braid 做的 reactive programming demo 和 Elm )。 React 有了抄 Elm 半套的 redux ,但使用者們沒有參透可以組合 redux action 再個別 dispatch 的 module 設計,反而搞出 redux toolkit 好在 runtime 前解決問題。
React Hooks 是個 algebraic effects 的破洞實作, JS 不支援 one-shot continuation ,於是大家得自己維護一個 dependency list ,還要靠 linter 來檢查有沒有誤用。同時還要面對一堆野生的碼農,認為自己不管 linter 的警告很厲害。
就算是個破洞實作,現在的 React Hooks 也能當個堪用的 runtime CPS transformation 工具。但官方不知道怎樣,想要實作個專門給 Promise
用的 CPS transformation hook 叫做 use
。
但也不全然都是壞事, Rust 有個跟 typeclasses 87% 像的 trait system , TypeScript 雖然 unsound 但可能是現在最方便取用的 dependent type system 。還有之前提過的, SJP 跑去 Epic 搞 logic programming language Verse 。
可能爛的是 web 圈圈失能的教育與傳承機制吧。