How to structure complex "state updating functions" in Clojure?

clojure, design-patterns, functional-programming

Solution

I would suggest to extract each of the steps in a nicely named function, so that you can use ->. Pseudo code:

(defn tic [g]
    (-> g
        inc-day
        random-weather
        grow-trees
        ...))

For any conditional logic, you can just do something similar to what you do in your g2 step.

Perhaps you will find synthread lib useful. I found this video very instructive.

Look also at cond-> to see how could you mix -> with some cond. For example your cond could look like:

(cond-> g
        true (update-in [:day] inc)
        (some-cond) some-update-fund
        true (update-in [:fu] fu-update))

Problem

I have a game state represented as a map and some logic that updates that state on every game 'tic'. But I can't figure out how to structure the update function in any sane way. What is the idiomatic pattern for structuring functions like this? Here is some pseudo code for what I want to do: ``` (defn tic [g] "Return an updated game" g1 = (update-in g [:day] inc) g2 = (if (some-cond) (some-update-func g1) g1) g3 = (update-in g2 [:fu] fu-update) ... many more ... g-last) ``` I don't really care about the intermediate states, but using the -> macro doesn't work (since there are some conditionals). A hack that works is using a local atom that is reset! for every 'line' in the update function. But that can't be how it's supposed to be done?!

Original source