-
-
Save michalmarczyk/386760 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns state.clj) | |
(comment | |
(def f | |
(statefully | |
x <- (*read*) | |
(*write* 42) | |
y <- (*read*) | |
(*update* str " was frobnicated!") | |
(return [x y]))) | |
(f :stateless) => [[:stateless 42] "42 was frobnicated"]) | |
(defn >> [mv f] | |
(fn [s] | |
(let [[_ s*] (mv s)] | |
(f s*)))) | |
(defn >>= [mv f] | |
(fn [s] | |
(let [[v s*] (mv s)] | |
((f v) s*)))) | |
(defn return [v] (fn [s] [v s])) | |
(defn parse:<- | |
([] []) | |
([x] [x]) | |
([x y] [x y]) | |
([x y z & more] | |
(lazy-seq | |
(if (= y '<-) | |
(cons ['<- x z] (apply parse:<- more)) | |
(cons x (apply parse:<- y z more)))))) | |
(defn do-state* [x & xs] | |
(if-not (seq xs) | |
x | |
(cond | |
(= :let x) `(let ~(first xs) ~(apply do-state* (rest xs))) | |
(not (vector? x)) `(>> ~x ~(apply do-state* xs)) | |
:else `(>>= ~(last x) | |
(fn [~(second x)] | |
~(apply do-state* xs)))))) | |
(defmacro statefully [& steps] | |
(apply do-state* (apply parse:<- steps))) | |
(defn *read* [& xs] | |
(fn [s] | |
(if (seq xs) | |
[(get-in s xs) s] | |
[s s]))) | |
(defn *write* [x] | |
(fn [s] [s x])) | |
(defn *update* [f & args] | |
(fn [s] [s (apply f s args)])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment