Skip to content

Instantly share code, notes, and snippets.

@divs1210
Last active February 13, 2018 11:41
Show Gist options
  • Save divs1210/1b73736e236b89650bede94cc241553f to your computer and use it in GitHub Desktop.
Save divs1210/1b73736e236b89650bede94cc241553f to your computer and use it in GitHub Desktop.
An Excercise in Time Travel
(ns history)
;; AN EXCERCISE IN TIME TRAVEL
;; ===========================
(defn hatom
"Atom that remembers previous states."
[x]
(atom {:value x
:history ()}))
(defn hderef
"Get current value of hatom."
[h]
(:value @h))
(defn hreset!
"Reset hatom to new value."
[h x]
(swap! h
(fn [{:keys [value history]}]
{:value x
:history (cons value history)})))
(defn hundo!
"Reset hatom to previous value, if one exists."
[h]
(swap! h
(fn [{:keys [history] :as m}]
(if (empty? history)
m
{:value (first history)
:history (rest history)}))))
(comment
(def h (hatom 1))
(hderef h) ;; => 1
(hreset! h 2)
(hderef h) ;; => 2
(hreset! h 3)
(hderef h) ;; => 3
(hundo! h)
(hderef h) ;; => 2
(hundo! h)
(hderef h) ;; => 1
(hundo! h)
(hderef h) ;; => 1
;; CHALLENGE!
;; Implement `hswap!` such that:
(hswap! h inc)
(hderef h) ;; => 2
(hundo! h)
(hderef h) ;; => 1
)
@divs1210
Copy link
Author

Extra chocolate for implementing redo!

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