【问题标题】:Handling errors with purity in Clojure?在 Clojure 中处理纯错误?
【发布时间】:2015-08-28 15:12:18
【问题描述】:

我正在开发一款使用大爆炸式编程风格的游戏,其中将整个状态定义为单个数据结构,并通过交换单个原子来管理状态更改。

在游戏中,我们不能信任客户端发送的数据,因此服务器必须预测某些动作无效的可能性并加以防范。当一个人编写一个交换世界状态的函数时,它可以从纯粹的开始;但是,必须考虑无效请求的可能性。我相信要在惯用的 Clojure 中实现不愉快的路径,只需抛出异常。所以现在可能是纯函数被副作用异常感染了。也许this 就是这样。

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

我的目标是将副作用推迟到最后一刻。我几乎没有涉足 Haskell 领域,但我知道 Either monad 的概念。当一个人考虑the happy and unhappy path 时,就会明白总有这两种可能性。这让我认为 swap! 本身是不够的,因为它忽略了不愉快的路径。这是这个想法的精神:

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

Clojure 社区是否采用了any more functional approaches 来处理异常?

【问题讨论】:

标签: exception-handling clojure functional-programming either


【解决方案1】:

在这种情况下,我倾向于采取几种不同的方法。如果在单个位置更新状态,我倾向于使用:

(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)

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 2014-02-27
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多