I have been studying patterns or the notion of idiomatic code in
Clojure.  The code in clojure.core has some good examples of proper
Clojure code and is well done.  For that reason I was a bit surprised
at the definition for re-groups:

(defn re-groups [^java.util.regex.Matcher m]
    (let [gc  (. m (groupCount))]
      (if (zero? gc)
        (. m (group))
        (loop [ret [] c 0]
          (if (<= c gc)
            (recur (conj ret (. m (group c))) (inc c))
            ret)))))

It seems like the loop/recur is non-idiomatic for this usage and could
be done with either a map or reduce.  Here is my rewrite attempting to
use common patterns:

(defn re-groups   [^java.util.regex.Matcher m]
    (let [gc  (. m (groupCount))
         [entire & groups :as ret] (map  #(.group m %) (range (inc gc)))]
       (if (seq groups)
        (apply vector ret)
        entire )))

The function is complicated by the fact that it either returns a
string or a vector depending on the number of groups.  This might be
better handled with a multimethod:

(defmulti re-groups (fn [^java.util.regex.Matcher m] (.groupCount m)))
(defmethod re-groups 0 [m] (.group m))
(defmethod re-groups :default [m]
        (let [idxs (range (inc (.groupCount m)))]
             (reduce #(conj %1 (.group m %2)) [] idxs)))

The final implementation with multi-methods seems cleaner to me in
making it clearer what the intent of the code is while allowing the
disjoint functionality.  Too bad the result of the defmulti filter is
not available to the methods.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
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

Reply via email to