Surely you must have rooted my box. That is my code more or less :) To the op: Use the immutable structures if possible. Make your types as basic as possible. Use Clojure's higer order functions reduce, map etc.... I consider loop as a last resort. Then your solution will closely match the problem.
2011/6/16 lambdatronic <gwjoh...@uvm.edu> > My 2c: > > Regarding learning how to model a complex data structure in a > functional paradigm: > > I can think of few resources which sum up the proper mindset you > need to get into > better than the canonical Clojure essay on state and identity, found > here: > > http://clojure.org/state > > Regarding how to model a graph in Clojure: > > I would suggest that you avoid thinking about refs unless you are > likely to need to > perform some kind of concurrent updates to your graph. A nested > associative data > structure should do the trick just fine. > > > (defrecord Node [foo bar baz]) > > (defn node [foo bar baz] (Node. foo bar baz)) > > (def the-graph {}) > > (defn add-node [g n] > (if (g n) > g > (assoc g n {:next #{} :prev #{}}))) > > (defn add-edge [g n1 n2] > (-> g > (add-node n1) > (add-node n2) > (update-in [n1 :next] conj n2) > (update-in [n2 :prev] conj n1))) > > (defn remove-edge [g n1 n2] > (-> g > (add-node n1) > (add-node n2) > (update-in [n1 :next] disj n2) > (update-in [n2 :prev] disj n1))) > > (defn remove-node [g n] > (if-let [{:keys [next prev]} (g n)] > ((comp > #(dissoc % n) > #(reduce (fn [g* n*] (remove-edge g* n* n)) % prev) > #(reduce (fn [g* n*] (remove-edge g* n n*)) % next)) > g) > g)) > > (defn contains-node? [g n] > (g n)) > > (defn contains-edge? [g n1 n2] > (get-in g [n1 :next n2])) > > (defn next-nodes [g n] > (get-in g [n :next])) > > ;; Assumes DAG > (defn depth-first-search [g root-node goal?] > (loop [open-list (list root-node)] > (when-first [n open-list] > (if (goal? n) > n > (recur (concat (next-nodes g n) (rest open-list))))))) > > > And there you go. A fast, functional DAG implementation that doesn't > use any mutable state. > > Happy hacking, > ~Gary > > > On Jun 16, 10:08 am, Colin Yates <colin.ya...@gmail.com> wrote: > > (newbie warning) > > > > Our current solution is an OO implementation in Groovy and Java. We > > have a (mutable) Project which has a DAG (directed acyclic graph). > > This is stored as a set of nodes and edges. There are multiple > > implementations of nodes (which may themselves be Projects). There > > are also multiple implementations of edges. > > > > My question isn't how to do this in a functional paradigm, my first > > question is *how do I learn* to do this in a functional paradigm. I > > want to be able to get the answer myself ;). To that end, are there > > any "domain driven design with functional programming" type resources? > > > > A more specific question is how do I model a graph? These graphs can > > be quite extensive, with mutations on the individual nodes as well as > > the structure (i.e. adding or removing branches). Does this mean that > > every every node would be a ref? I think the general answer is that > > the aggregate roots are refs, meaning they are an atomic block, but is > > there any more guidance? > > -- > 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 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