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

Reply via email to