2

我正在開發一種遊戲,使用大規模的編程風格,將整個狀態定義爲單個數據結構,並通過交換單個原子來管理狀態更改。在Clojure中處理純度錯誤?

在遊戲中,我們不能相信客戶端發送的數據,因此服務器必須預見到一些動作會失效並防範它的可能性。當人們寫出一個交換世界狀態的函數時,它可以開始純粹;但是,必須考慮無效請求的可能性。我相信在慣用的Clojure中會產生不愉快的路徑,只會拋出異常。所以現在可能是純粹的功能會感染副作用的異常。也許this是它必須的。

(try 
    (swap! world update-game) ;possible exception here! 
    (catch Exception e 
    (>! err-chan e)) 

我的目標是推遲副作用,直到最後一刻。我幾乎沒有進入哈斯克爾的土地,但我知道任何一個monad的概念。當人們認爲the happy and unhappy path理解總有這2種可能性。這讓我覺得swap!本身是不夠的,因爲它忽略了不快樂的路徑。這裏的想法的噴出:

(swap-either! err-chan world update-game) ;update-game returns either monad 

已處理異常採用any more functional approaches Clojure的社區?

+0

http://adambard.com/blog/acceptable-error-handling-in-clojure/ – Mario

回答

2

我傾向於在這種情況下采取幾種不同的方法。如果狀態是在一個位置更新我傾向於去有:

(try 
    (swap! world update-game) ;possible exception here! 
    (catch Exception e 
    (>! err-chan e) 
    world) ;; <--- return the world unchanged 

,或者如果它在很多地方廣告拋出的異常給地方掉一個觀察者的設置!被稱爲並且不改變狀態:

user> (def a (atom 1)) 
#'user/a 
user> (add-watch a :im-a-test (fn [_ _ _ new-state] 
           (if (even? new-state) 
            (throw (IllegalStateException. "I don't like even numbers"))))) 
#object[clojure.lang.Atom 0x5c1dc37e {:status :ready, :val 1}] 
user> (swap! a + 2) 
3 
user> (swap! a + 3) 
IllegalStateException I don't like even numbers user/eval108260/fn--108261 (form-init8563497779572341831.clj:2)