On Aug 25, 8:45 am, Stuart Halloway <[EMAIL PROTECTED]> wrote: > For Java.next [1,2] part 3, I am porting Daniel Spiewak's color > example [3] to Clojure. Here's the Clojure version: > > (defstruct color :red :green :blue) > > (defn red [v] (struct color v 0 0)) > (defn green [v] (struct color 0 v 0)) > (defn blue [v] (struct color 0 0 v)) > > (defn keys-with-value-matching [map test-fn] > (for [pair (map identity map) :when (test-fn (last pair))] > (first pair))) > > (defn basic-colors-in [color] > (keys-with-value-matching color (comp not zero?))) > > (defmulti color-string basic-colors-in) > (defmethod color-string [:red] [color] (str "Red: " (:red color))) > (defmethod color-string [:green] [color] (str "Green: " (:green color))) > (defmethod color-string [:blue] [color] (str "Blue: " (:blue color))) > (defmethod color-string :default [color] > (str "Red: " (:red color) ", Green: " (:green color) ", Blue: > " (:blue color))) > > I am reasonably happy with the struct and the defmulti, but I am sure > there is a more elegant way to do basic-colors-in and especially keys- > with-value-matching. What is a more idiomatic approach? >
It's a bit apples and oranges emulating pattern matching and case classes with multimethods, but very illustrative. It's important to note that the Scala code is using type tags, not values, in doing the match, so I think using tags rather than looking for non-zero values is more similar: (defstruct color :red :green :blue) (defn color-class [name r g b] (assoc (struct color r g b) :tag name)) (defn red [v] (color-class :red v 0 0)) (defn green [v] (color-class :green 0 v 0)) (defn blue [v] (color-class :blue 0 0 v)) (defmulti color-string :tag) (defmethod color-string :red [c] (str "Red: " (:red c))) (defmethod color-string :green [c] (str "Green: " (:green c))) (defmethod color-string :blue [c] (str "Blue: " (:blue c))) (defmethod color-string :default [{:keys [red green blue]}] (str "Color, R: " red ", G: " green ", B: " blue)) A critical difference, IMO, is that pattern matches are closed, and multimethods are open: (defn orange [r g] (color-class :orange r g 0)) (defmethod color-string :orange [{:keys [red green]}] (str "Orange, R: " red ", G: " green)) Rich --~--~---------~--~----~------------~-------~--~----~ 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 To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---