babygau
babygau

Reputation: 1581

Explain clojure map reducer implementation

I'm trying to make head or tail of core.reducers library and I run into the following line of codes about r/map:

(defmacro ^:private defcurried
  "Builds another arity of the fn that returns a fn awaiting the last
  param"
  [name doc meta args & body]
  (do-curried name doc meta args body))

(defn- do-rfn [f1 k fkv] 
  `(fn
     ([] (~f1))
     ~(clojure.walk/postwalk
       #(if (sequential? %)
          ((if (vector? %) vec identity)
           (core/remove #{k} %))
          %)
       fkv)
     ~fkv))

(defmacro ^:private rfn
  "Builds 3-arity reducing fn given names of wrapped fn and key, and k/v impl."
  [[f1 k] fkv]
  (do-rfn f1 k fkv))

(defcurried map
  "Applies f to every value in the reduction of coll. Foldable."
  {:added "1.5"}
  [f coll]
  (folder coll
          (fn [f1]
            (rfn [f1 k]
                 ;; the following is k/v implementation but
                 ([ret k v] ;; why a `vector` is placed in the beginning of a list???
                  (f1 ret (f k v)))))))

In defcurried map implementation, the rfn looks strange & unusual to me because I don't understand why [ret k v] is put in the beginning of a list. Can anyone please explain?

Upvotes: 1

Views: 113

Answers (1)

noisesmith
noisesmith

Reputation: 20194

When called as a function, a vector, keyword, symbol, or hash-map will all end up invoking get as appropriate.

user> (get [:a :b :c] 1)
:b
user> ([:a :b :c] 1)
:b

Upvotes: 1

Related Questions