Skip to content

Instantly share code, notes, and snippets.

@divs1210
Last active April 30, 2020 05:11
Show Gist options
  • Save divs1210/9b4a1987ab93425a251b67cbcaf7fbf9 to your computer and use it in GitHub Desktop.
Save divs1210/9b4a1987ab93425a251b67cbcaf7fbf9 to your computer and use it in GitHub Desktop.
Simple, fast fsm for all your needs
;; Implementation
;; ==============
(defn- return
[base stack]
(reduce (fn [acc f]
(f acc))
base
stack))
(defn run-fsm
[fsm & args]
(loop [{:keys [do args then to on-recv]} (apply fsm args)
stack []]
(case do
:return
(return args stack)
:goto
(recur (to args)
(concat then stack)))))
;; Examples
;; ========
;; self recursion
;; ==============
(defn fact-fsm [n]
(if (< n 2)
{:do :return
:args 1}
{:do :goto
:to fact-fsm
:args (dec n)
:then [#(*' n %)]}))
user> (run-fsm fact-fsm 5000)
;; => 42285779266055....
;; mutual recursion
;; ================
(declare is-odd?)
(defn is-even? [n]
(if (zero? n)
{:do :return
:args true}
{:do :goto
:to is-odd?
:args (dec n)}))
(defn is-odd? [n]
(if (zero? n)
{:do :return
:args false}
{:do :goto
:to is-even?
:args (dec n)}))
user> (run-fsm is-even? 5000)
;; => true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment