On Sat, January 11, 2014 9:22 pm, Alex Baranosky wrote:
> There is a class of problems where you want to track some state as you
process a seq
This is an interesting exercise. I find said class of problem comes up
fairly frequently and I usually end up with something scary-looking using
reduce or lazy-seq that I'm never quite satisfied with. I often feel
there's some missing flow control mechanism just out of reach.
As another point of comparison here's a straightforward imperative version
(of the simplified problem):
(defn unique [words]
(let [occurrences (java.util.HashMap.)]
(for [word words]
(let [n (get occurrences word 0)]
(.put occurrences word (inc n))
(if (zero? n) word (str word "_" n))))))
i.e. "if a tree falls in the woods..." style mutation. :-)
> and transduce.lazy/map-state enables you to do that
(https://github.com/brandonbloom/transduce)
The imperative solution led me towards something like the "for"-like form
of map-state. A macro that's a hybrid of "for" and "loop" such that it
takes both for and loop style bindings:
(defn unique [words]
(for-loop [word words] [occurrences {}]
(let [n (get occurences word 0)]
(yield (if (zero? n) word (str word "_" n))
(assoc occurrences word (inc n))))))
Imagine "yield" is somewhat like "recur" in that it takes new values to
bind for the next iteration but its first argument is the sequence element
to return for the current step. Like recur yield must be in the tail call
position.
The above might expand into this:
(defn uniquify [words format]
((fn uniquify* [occurrences words]
(lazy-seq
(let [[word & rest] words
n (get occurrences word 0)]
(when word
(cons (if (zero? n) word (str word "_" n))
(uniquify* (assoc occurrences word (inc n))
rest))))))
{} words))
--
--
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
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.