I'm working on a game using the big-bang style of programming where one defines the entire state as a single data structure and manages state change by swapping against a single atom.
In a game we cannot trust data sent by the client thus the server has to anticipate the possibility that some moves will be invalid and guard against it. When one writes a function for swapping world state it can start out pure; however, one must consider the possibility of invalid requests. I believe to effect the unhappy path in idiomatic Clojure one simply throws exceptions. So now functions that might have been pure are infected with side-effecting exceptions. Perhaps this is as it has to be.
(try
(swap! world update-game) ;possible exception here!
(catch Exception e
(>! err-chan e))
My aim is to defer side-effects until the last possible moment. I've hardly forayed into Haskell land but I know the concept of the Either monad. When one considers the happy and unhappy path one understands there are always these 2 possibilities. This has me thinking that swap!
by itself is insufficient since it ignores the unhappy path. Here's the spirt of the idea:
(swap-either! err-chan world update-game) ;update-game returns either monad
Has the Clojure community adopted any more functional approaches for handling exceptions?
I tend to take a couple different approaches in cases like this. If the state is being updated in a single location I tend to go with:
or if it's set in lots of places ad a watcher that throws the exception back to the place where swap! was called and doesn't change the state: