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 clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com 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 clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.