函數式程式設計
一句令人驚訝的話:
函數式語言中的變數不會改變 (do not vary)
列印前 25 個整數的平方
比較一下 Clojure 程式和 Java 程式之間的差異
- Java
1 | public class Squint { |
其中是利用一個可變變數(mutable variable) i,
- Clojure
1 | (println |
在 Clojure 中,不存在這種可變變數,像 x 被初始化後,永遠不會被修改
不可變與架構
為什麼要關心可變性呢?因為所有的競爭條件 (race condition)、死結條件 (deadlock)、平行更新問題 (concurrent update problem) 都來自於可變變數。如果沒有可變變數,就不會遇到上面的問題了。
但是
不變性是否可行?如果有無限資源,是可行的。不過在現實世界中,需要做一些折衷。
可變性分離
最常見的折衷方案之一,將元件分為,可變和不可變的元件。
重點是結構良好的應用程式將被分離,分貝到那些不可變變數的元件中和可變變數的元件中。透過適當的規範,來支援這種分離以保護那些可變的變數。
事件來源
事件來源是種策略,我們儲存的是交易而非狀態。而當需要取得狀態時,我們只是簡單的從源頭開始應用所有的交易。
更重要的是,沒有任何東西會從這樣的資料儲存空間中被刪除或更新,因此不是 CRUD 而是 CR。所以也就不會有平行化的問題。
這正式你的原始碼控制系統的工作方式!
這些方案在過去的實作中,默默的被使用到了。看來可以使用上可以依此在做得更乾淨一些,做半套往往會有一些延伸的問題。
總結
- 結構化程式設計就是在直接控制移轉上加上規範
- 物件導向程式設計就是在間接控制移轉上加上規範
- 函數式程式設計就是在變數賦值上加上規範
都是限制了我們寫程式的方法,沒有增強我們的力量或能力,過去半個世紀所學到的都是,哪些不該做 (what not to do)
限制通常是為了讓事情 under control,「合理的管理」不就是這樣嗎?