Clev3r
Clev3r

Reputation: 1578

"->>" macro and iterative function application

I'm working through a book on clojure and ran into a stumbling block with "->>". The author provides an example of a comp that converts camelCased keywords into a clojure map with a more idiomatic camel-cased approach. Here's the code using comp:

(require '[clojure.string :as str])                               

(def camel->keyword (comp keyword
                          str/join
                          (partial interpose \-)
                          (partial map str/lower-case)
                          #(str/split % #"(?<=[a-z])(?=[A-Z])")))

This makes a lot of sense, but I don't really like using partial all over the place to handle a variable number of arguments. Instead, an alternative is provided here:

(defn camel->keyword
  [s]
  (->> (str/split s #"(?<=[a-z])(?=[A-Z])")
    (map str/lower-case)
    (interpose \-)
    str/join
    keyword))

This syntax is much more readable, and mimics the way I would think about solving a problem (front to back, instead of back to front). Extending the comp to complete the aforementioned goal...

(def camel-pairs->map (comp (partial apply hash-map)
                            (partial map-indexed (fn [i x]
                                                   (if (odd? i)
                                                     x
                                                     (camel->keyword x))))))

What would be the equivalent using ->>? I'm not exactly sure how to thread map-indexed (or any iterative function) using ->>. This is wrong:

(defn camel-pairs->map 
  [s]
  (->> (map-indexed (fn [i x]
         (if (odd? i)
           x
           (camel-keyword x))) 
       (apply hash-map)))

Upvotes: 3

Views: 126

Answers (1)

A. Webb
A. Webb

Reputation: 26446

Three problems: missing a parenthesis, missing the > in the name of camel->keyword, and not "seeding" your ->> macro with the initial expression s.

(defn camel-pairs->map [s]
  (->> s
      (map-indexed 
        (fn [i x] 
          (if (odd? i) 
            x 
            (camel->keyword x)))) 
       (apply hash-map)))

Is this really more clear than say?

(defn camel-pairs->map [s] 
  (into {} 
    (for [[k v] (partition 2 s)] 
      [(camel->keyword k) v])))

Upvotes: 6

Related Questions