Well, I wrote the code, so I suppose I should comment on it a bit. The ioc_macros use a very loosely defined version of the state-monad. I don't know if the functions/macros follow all the monad laws, and I really don't care, but here's the problem:
I needed to be able to track some state while parsing the clojure code. I needed to be able to define blocks while defining other blocks, to have instructions reference each other, etc. All this could be done with a atom, but I really don't like mutable state. So I decided to write the entire thing in a fully immutable way. Thus, the first step is to start defining functions that return functions that will take a state: (defn assoc-plan [k v] (fn [state] [nil (assoc state k v)])) So each "monadic function" is a function that takes a state, and returns a vector of [value new-state]. This allows me to write functions like add-instruction that both add an instruction to a block and also return a id to that instruction. All the other functions in the code are built off this simple concept. gen-plan then wires them all up together, and is basically monadic "bind", except it's optimized to use lets instead of nested fns. All this allows the parsing code to remain rather simple, while tracking state, and remaining fully immutable. The code below looks as if it is mutating state, but is actually fully immutable. (defmethod sexpr-to-ssa 'if [[_ test then else]] (gen-plan [test-id (item-to-ssa test) then-blk (add-block) else-blk (add-block) final-blk (add-block) _ (add-instruction (->CondBr test-id then-blk else-blk)) _ (set-block then-blk) then-id (item-to-ssa then) _ (if (not= then-id ::terminated) (gen-plan [_ (add-instruction (->Jmp then-id final-blk))] then-id) (no-op)) _ (set-block else-blk) else-id (item-to-ssa else) _ (if (not= else-id ::terminated) (gen-plan [_ (add-instruction (->Jmp else-id final-blk))] then-id) (no-op)) _ (set-block final-blk) val-id (add-instruction (->Const ::value))] val-id)) Most of the time, I recommend people start reading the at functions such as add-block, get-block, set-block, etc. Ignore the implementation of gen-plan, and just examine how it's used. After about 30 minutes the light will go on, and it'll all make sense. Pretty printing (via the debug function) the output of parse-to-state-machine will also help you make sense of what's being constructed. I hope this helps. Timothy Baldridge On Fri, Jul 26, 2013 at 8:51 AM, john <john.vie...@gmail.com> wrote: > Hi, > I am trying to understand the code in > ioc_macros.clj<https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/ioc_macros.clj> > . > I stumbled on the macro gen-plan which doc reads "Allows a user to define > a state monad binding plan" > I am wondering what makes the macro a "state monad" and how does it > simplify the building of the state-machine data structure? > > Many Greetings > John > > > > > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.