Skip to content

Instantly share code, notes, and snippets.

@stuarthalloway
Last active November 25, 2017 19:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stuarthalloway/291f2e5551b95fdf8de5d5863e57a095 to your computer and use it in GitHub Desktop.
Save stuarthalloway/291f2e5551b95fdf8de5d5863e57a095 to your computer and use it in GitHub Desktop.
Update state with a pure function
;; fixed version of 'state' at http://mishadoff.com/blog/clojure-design-patterns/#episode-3-state
;; takeaway: if you call 'swap!' twice on the same atom, you are probably making a mistake
(def user {:name "Jackie Brown"
:balance 0
:subscription? false})
(def ^:const SUBSCRIPTION_COST 30)
(defn pay
[{:keys [balance name subscription?]} amount]
(let [balance (+ balance amount)]
(if (and (> balance SUBSCRIPTION_COST) (not subscription?))
{:name name :subscription? true :balance (- balance SUBSCRIPTION_COST)}
{:name name :subscription? subscription? :balance balance})))
(reductions pay user [10 25 25])
;; now you can put user into any reference type you like: atom, ref, agent...
@mfikes
Copy link

mfikes commented Nov 25, 2017

Excellent purification :)

One small fix: > should be >= so that (reductions pay user [10 20]) ends up with :subscription? true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment