;; Better yet... (if (or (and (multi? graph) (not= 2 (count edge))) (and (looped? graph) (not (distinct? edge)))) graph (let [e (if (directed? edge) (vec edge) (set edge))] (update-in graph [:edges] conj e))))
On Thu, Sep 5, 2013 at 2:22 PM, Alex Baranosky < alexander.barano...@gmail.com> wrote: > I'd just use a cond to flatten a nested if. That's usually all you need, > imo. > > > On Thu, Sep 5, 2013 at 1:07 PM, Bruno Kim Medeiros Cesar < > brunokim...@gmail.com> wrote: > >> Thanks for your suggestion, didn't know about that! One of the things >> that made someone say that "Clojure looks like a language from the near >> future". However, I'm having a hard time using it with its full power. >> Could you recommend any other resource, besides the overview page on >> github, to learn pattern matching? Maybe a project that uses them? >> >> For the record, my code uses a simple truth table now: >> >> >> (defn add-edge >> ([g v1 v2 & vs] (add-edge g (concat [v1 v2] vs))) >> ([g edge] >> (let [two? (= 2 (count edge)) >> dist? (apply distinct? edge) >> e (match [(hyper? g) (looped? g)] ; e will be nil if edge is >> invalid for this graph >> [false false] (when (and two? dist?) edge) >> [false true ] (when two? edge) >> [true false] (when dist? edge) >> [true true ] edge] >> (if e >> (update-in g [:edges] conj (if (directed? g) (vec e) (set e))) >> g)))) >> >> On Wednesday, September 4, 2013 7:07:06 PM UTC-3, Leonardo Borges wrote: >> >>> You could use pattern matching with core.match >>> On 05/09/2013 6:57 AM, "Bruno Kim Medeiros Cesar" <bruno...@gmail.com> >>> wrote: >>> >>>> I'm writing (another) basic graph library, and would like to treat >>>> inputs depending on the type of the graph. A graph can be >>>> >>>> - Directed, in which case edges are vectors. Otherwise, edges are >>>> sets; >>>> - Looped, allowing edges from a node to itself; >>>> - Pseudo (or multi), allowing multiples edges between the same >>>> endpoints; and >>>> - Hyper, allowing edges with more than two vertices. >>>> >>>> To illustrate better these characteristics you can think of a >>>> scientific publication network as a directed, looped, pseudo-hypergraph. >>>> Vertices are authors, and edges are articles containing multiple >>>> researchers (hyper) who can publish alone (looped). There are multiple >>>> articles between the same researchers (pseudo) and in some contexts author >>>> order matters (directed). >>>> >>>> Now, I've created a flowchart <http://imgur.com/IdgsGFG> to decide if >>>> an edge should be conjed in a graph :edges entry, that leads to the >>>> following straightforward function: >>>> (defn add-edge >>>> ([graph v1 v2 & vs] (add-edge graph (concat [v1 v2] vs))) >>>> ([graph edge] >>>> (if (and (multi? graph) (not= 2 (count edge))) >>>> graph >>>> (if (and (looped? graph) (not (distinct? edge))) >>>> graph >>>> (let [e (if (directed? edge) (vec edge) (set edge))] >>>> (update-in graph [:edges] conj e)))))) >>>> >>>> That looks ugly and a pattern that could propagate in a codebase. So I >>>> tried to factor out multimethods from it, and ended with the following: >>>> >>>> (defmulti ^:private add-edge0 (fn [g e] (hyper? g))) >>>> (defmulti ^:private add-edge1 (fn [g e] (looped? g))) >>>> (defmulti ^:private add-edge2 (fn [g e] (directed? g))) >>>> (defn ^:private add-edge3 [g e] >>>> (update-in g [:edges] conj e)) >>>> >>>> (defmethod add-edge0 :hyper [g e] (add-edge1 g e)) >>>> (defmethod add-edge0 :default [g e] (if (= 2 (count e)) >>>> ** (add-edge1 g e) >>>> ** g)) >>>> (defmethod add-edge1 :looped [g e] (add-edge2 g e)) >>>> (defmethod add-edge1 :default [g e] (if (distinct? e) >>>> ** (add-edge2 g e) >>>> ** g)) >>>> (defmethod add-edge2 :directed [g e] (add-edge3 g (vec e))) >>>> (defmethod add-edge2 :default [g e] (add-edge3 g (set e))) >>>> >>>> (defn add-edge >>>> ([g v1 v2 & vs] (add-edge g (concat [v1 v2] vs))) >>>> ([g edge] (add-edge0 g edge))) >>>> >>>> That doesn't look much better, as the amount of boilerplate increased, >>>> but at least the concerns for each type are separated. >>>> >>>> Do you have any suggestions on how to improve this design? Thanks for >>>> any consideration! >>>> >>>> Bruno Kim Medeiros Cesar >>>> Engenheiro de Computação >>>> Pesquisador em Redes Complexas >>>> www.brunokim.com.br >>>> >>>> -- >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clo...@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+u...@**googlegroups.com >>>> >>>> For more options, visit this group at >>>> http://groups.google.com/**group/clojure?hl=en<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+u...@**googlegroups.com. >>>> >>>> For more options, visit >>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out> >>>> . >>>> >>> -- >> -- >> 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. >> > > -- -- 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.