Skip to content

Instantly share code, notes, and snippets.

@jaycfields
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaycfields/42663bc7d1c5f119b73c to your computer and use it in GitHub Desktop.
Save jaycfields/42663bc7d1c5f119b73c to your computer and use it in GitHub Desktop.
;; top level, used only once
(defn only-used-once [r {:keys [foo]}]
(if (even? foo)
(+ r foo)
r))
(defn sum-my-stuff1 [coll]
(reduce only-used-once 0 coll))
;; anonymous fn, inline
(defn sum-my-stuff2 [coll]
(reduce
(fn [result {:keys [foo]}]
(if (even? foo) (+ result foo) result))
0
coll))
;; multi-arity to encapsulate both
(defn sum-my-stuff3
([coll] (sum-my-stuff3 0 coll))
([result [{:keys [foo] :as hd} & tl]]
(cond
(nil? hd) result
(even? foo) (recur (+ result foo) tl)
:else (recur result tl))))
;; loop, no other fns needed.
(defn sum-my-stuff4 [coll]
(loop [result 0 [{:keys [foo] :as hd} & tl] coll]
(cond
(nil? hd) result
(even? foo) (recur (+ result foo) tl)
:else (recur result tl))))
@navision
Copy link

navision commented Oct 8, 2014

;; top level
(defn- add-even-foo [r {:keys [foo]}]
  (if (even? foo)
    (+ r foo)
    r))

(defn sum-my-stuff [coll]
  (reduce add-even-foo 0 coll))

;;or

(defn sum-my-stuff2 [coll]
  (letfn [(add-even-foo [r {:keys [foo]}]
              (if (even? foo)
                (+ r foo)
                r))]
    (reduce add-even-foo 0 coll)))

;; reducer version
(require '[clojure.core.reducers :as r])
(defn sum-my-stuff3 [coll]
  (r/fold + (r/filter even? (r/map :foo coll))))

@jaycfields
Copy link
Author

indeed, letfn is a possibility. you like that the best?

@hlship
Copy link

hlship commented Oct 8, 2014

I would tend to favor sum-my-stuff1, but with only-used-once as a private function. sum-my-stuff2 fails my "at a glance" test, but that's HIGHLY subjective.

sum-my-stuff3 and sum-my-stuff4 fail for me, because if it can be done reasonably with reduce, it should be done so, unless there are some outside concerns.

@logosity
Copy link

logosity commented Oct 8, 2014

I think I like the letfn/reduce approach best because I prefer reduce over recur here (feels like reimplementing reduce) and yet the anonymous fn version isn't obvious as to its intent (which might just be how it inlines into the reduce statement). In general, I prefer anonymous fns for obvious single-use(able) predicates and letfn for not obvious ones. I like reusable named, predicates best of all, because then it feels like I created a new tool.

@logosity
Copy link

logosity commented Oct 8, 2014

As a side-note: the part I found most opaque is the parameter destructuring, but I then again, I rarely use :keys (or mebbe that cause/effect is the other way round).

@navision
Copy link

navision commented Oct 8, 2014

;; transducer version - the future?
(defn sum-my-stuff-inf [coll]
  (transduce (comp (map :foo) (filter even?)) + coll))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment