Skip to content

Instantly share code, notes, and snippets.

@jaycfields
Last active August 29, 2015 14:07
Show Gist options
  • Select an option

  • Save jaycfields/42663bc7d1c5f119b73c to your computer and use it in GitHub Desktop.

Select an option

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

navision commented Oct 8, 2014

Copy link
Copy Markdown
;; 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
Copy Markdown
Author

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

@hlship

hlship commented Oct 8, 2014

Copy link
Copy Markdown

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

logosity commented Oct 8, 2014

Copy link
Copy Markdown

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

logosity commented Oct 8, 2014

Copy link
Copy Markdown

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

navision commented Oct 8, 2014

Copy link
Copy Markdown
;; 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