<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged transducers</title>
<link>https://ask.clojure.org/index.php/tag/transducers</link>
<description></description>
<item>
<title>Dedupe doesn't mention statefullness in docstring</title>
<link>https://ask.clojure.org/index.php/13636/dedupe-doesnt-mention-statefullness-in-docstring</link>
<description>&lt;p&gt;Unlike all other core functions which can return a stateful transducer, &lt;code&gt;dedupe&lt;/code&gt; doesn't mention this in its docstring. E.g. &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;drop-while&lt;/code&gt; etc. all say:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Returns a stateful transducer when no collection is provided.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But &lt;code&gt;dedupe&lt;/code&gt; just says:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Returns a transducer when no collection is provided.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
<category>Docs</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13636/dedupe-doesnt-mention-statefullness-in-docstring</guid>
<pubDate>Mon, 22 Jan 2024 12:22:44 +0000</pubDate>
</item>
<item>
<title>Missing stateful string accumulator function (for transduce target)</title>
<link>https://ask.clojure.org/index.php/13294/missing-stateful-string-accumulator-function-transduce-target</link>
<description>&lt;p&gt;If you have a transducer chain that makes a stream of strings, you might want to accumulate them at the end into a string. Existing functions like &lt;code&gt;str&lt;/code&gt; will generate a lot of overhead as there is no stateful accumulator you can maintain.&lt;/p&gt;
&lt;p&gt;What you really want is a StringBuilder that accumulates, and emits the string at finalization.&lt;/p&gt;
&lt;p&gt;String joining could then be something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(transduce (interpose &quot;,&quot;) str! coll)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;extensible with more transducers as needed.&lt;/p&gt;
&lt;p&gt;cgrand's xforms lib has something like this: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/cgrand/xforms/blob/2079b74271b858b6a91dcb87bc58f3b93ea0b19c/src/net/cgrand/xforms/rfs.cljc#L145-L147&quot;&gt;https://github.com/cgrand/xforms/blob/2079b74271b858b6a91dcb87bc58f3b93ea0b19c/src/net/cgrand/xforms/rfs.cljc#L145-L147&lt;/a&gt;&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13294/missing-stateful-string-accumulator-function-transduce-target</guid>
<pubDate>Fri, 15 Sep 2023 19:04:56 +0000</pubDate>
</item>
<item>
<title>Use transducer arity of `into` in `clojure.walk` namespace</title>
<link>https://ask.clojure.org/index.php/13281/use-transducer-arity-of-into-in-clojure-walk-namespace</link>
<description>&lt;p&gt;It's simple. Just like that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; clojure.walk/walk:
(outer (reduce (fn [r x] (conj r (inner x))) form form))
=&amp;gt; (outer (into form (map inner) form))
(outer (into (empty form) (map inner form)))
=&amp;gt; (outer (into (empty form) (map inner) form))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; clojure.walk/keywordize-keys:
(postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)
=&amp;gt; (postwalk (fn [x] (if (map? x) (into {} (map f) x) x)) m)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; clojure.walk/strigify-keys:
(postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)
=&amp;gt; (postwalk (fn [x] (if (map? x) (into {} (map f) x) x)) m)
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13281/use-transducer-arity-of-into-in-clojure-walk-namespace</guid>
<pubDate>Wed, 13 Sep 2023 22:49:05 +0000</pubDate>
</item>
<item>
<title>Efficient merge</title>
<link>https://ask.clojure.org/index.php/13206/efficient-merge</link>
<description>&lt;p&gt;I was wondering why the &lt;code&gt;merge&lt;/code&gt; function doesn't use transients and if there could be a better version of that.&lt;/p&gt;
&lt;p&gt;Instead of this:&lt;br&gt;
&lt;code&gt;(defn merge [&amp;amp; maps] (when (some identity maps) (reduce #(conj (or %1 {}) %2) maps)))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;we can use transducers to keep the code still easy to read and have better performance:&lt;br&gt;
&lt;code&gt;(defn merge [&amp;amp; maps] (when (some identity maps) (into {} cat maps)))&lt;/code&gt;&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13206/efficient-merge</guid>
<pubDate>Sat, 26 Aug 2023 18:28:54 +0000</pubDate>
</item>
<item>
<title>There is currently no option for `partition` to use the advantage of transducers.</title>
<link>https://ask.clojure.org/index.php/13187/there-currently-option-for-partition-advantage-transducers</link>
<description>&lt;p&gt;As said in the title. There are several options to solve this problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Introduce the 1-arity only for &lt;code&gt;(partition n coll)&lt;/code&gt;, which keeps the current standard pattern. It doesn't however allow the other arities and attempting to call &lt;code&gt;(partition n step)&lt;/code&gt; or &lt;code&gt;(partition n step coll)&lt;/code&gt; would result to unexpected behavior. That could be solved by checks of &lt;code&gt;(seqable? step-or-coll)&lt;/code&gt; or similar things.&lt;/li&gt;
&lt;li&gt;The 1-arity would be passed as a vector. That could solve the arity collision problem but itwould break the pattern.&lt;/li&gt;
&lt;li&gt;Introduce a function like &lt;code&gt;partition-xf&lt;/code&gt; that would do the work. The only issues could be that this function only returns a transducer, which is not common and that some people could expect the &lt;code&gt;partition&lt;/code&gt; function to return a transducer if called like &lt;code&gt;(partition n step)&lt;/code&gt;, but I think it's just about getting used to it like everything else.&lt;/li&gt;
&lt;/ol&gt;
</description>
<category>Transducers</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13187/there-currently-option-for-partition-advantage-transducers</guid>
<pubDate>Tue, 22 Aug 2023 18:23:14 +0000</pubDate>
</item>
<item>
<title>Use transducers on clojure.core lazy sequence transformations</title>
<link>https://ask.clojure.org/index.php/12847/use-transducers-clojure-core-lazy-sequence-transformations</link>
<description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I heard that if transducers were included before in the language, they would have been used as the building blocks of all sequence lazy operations. Since they were added later, you need to adapt your code a bit to use transducers. And I was wondering why using &lt;code&gt;eduction&lt;/code&gt; is not an option? I'm trying to understand the scenarios in which it's not a performance advantage to define the sequence lazy operations like this (of course assuming the same behaviour):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn map
  ([f] ;; the standard transducer definition
   ,,,)
  ([f coll]
   (eduction (map f) coll))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I'm trying to understand given the assumption (which might be an erroneous assumption) that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(-&amp;gt;&amp;gt; (range 5000000)
     (eduction (map inc))
     (eduction (filter odd?))
     (eduction (map dec))
     (eduction (filter even?))
     (eduction (map (fn [n] (+ 3 n))))
     (eduction (filter odd?))
     (eduction (map inc))
     (eduction (filter odd?))
     (eduction (map dec))
     (eduction (filter even?))
     (eduction (map (fn [n] (+ 3 n))))
     (eduction (filter odd?))
     (into []))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is the same as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(-&amp;gt;&amp;gt; (range 5000000)
     (map inc)
     (filter odd?)
     (map dec)
     (filter even?)
     (map (fn [n] (+ 3 n)))
     (filter odd?)
     (map inc)
     (filter odd?)
     (map dec)
     (filter even?)
     (map (fn [n] (+ 3 n)))
     (filter odd?)
     (into []))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12847/use-transducers-clojure-core-lazy-sequence-transformations</guid>
<pubDate>Tue, 11 Apr 2023 06:55:00 +0000</pubDate>
</item>
<item>
<title>group-by reducing function</title>
<link>https://ask.clojure.org/index.php/12097/group-by-reducing-function</link>
<description>&lt;p&gt;I often find myself writing a reducing function that does what &lt;code&gt;group-by&lt;/code&gt; does. It would be convenient to have &lt;code&gt;group-by&lt;/code&gt; return a reducing function (without needing to import Christophe Grand's xforms lib). So instead of writing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  (-&amp;gt;&amp;gt; (range 10)
       (transduce (map inc) (completing (fn [r x] (update r (even? x) (fnil conj []) x))) {}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I could write:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  (-&amp;gt;&amp;gt; (range 10)
       (transduce (map inc) (group-by even?)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maybe something like this?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  (defn group-by
    ([f]
     (fn
       ([] (transient {}))
       ([r] (persistent! r))
       ([r x]
        (let [k (f x)]
          (assoc! r k (conj (get r k []) x))))))
    ([f coll]  
     (persistent!
      (reduce
       (fn [ret x]
         (let [k (f x)]
           (assoc! ret k (conj (get ret k []) x))))
       (transient {}) coll))))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Transducers</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12097/group-by-reducing-function</guid>
<pubDate>Tue, 02 Aug 2022 11:55:38 +0000</pubDate>
</item>
<item>
<title>Cast to Map$Entry Exception When Trying to (Into {}) After Sequence Operations</title>
<link>https://ask.clojure.org/index.php/11879/cast-mapentry-exception-trying-after-sequence-operations</link>
<description>&lt;p&gt;Is it intended behavior to get this exception  :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class clojure.lang.Keyword cannot be cast to class java.util.Map$Entry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;on this piece of code :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def a [[&quot;Active&quot; :Transit-RLC &quot;Active&quot;]])

(-&amp;gt;&amp;gt; a
     (transduce
       (comp 
             (map drop-last)
             (map reverse))
       conj [])
     (into {}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;changing the transducer to &lt;code&gt;(map (-&amp;gt; [(second %) (first %)])&lt;/code&gt; solves the issue.&lt;br&gt;
Thanks&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11879/cast-mapentry-exception-trying-after-sequence-operations</guid>
<pubDate>Sun, 08 May 2022 09:17:12 +0000</pubDate>
</item>
<item>
<title>dedupe and partition-by depending on magic value</title>
<link>https://ask.clojure.org/index.php/11835/dedupe-and-partition-by-depending-on-magic-value</link>
<description>&lt;p&gt;I noticed &lt;code&gt;dedupe&lt;/code&gt; and the transducer-returning arity of &lt;code&gt;partition-by&lt;/code&gt; use the magic value &lt;code&gt;:clojure.core/none&lt;/code&gt; to indicate the start of processing. There are some cases where this results in an incorrect result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;;;; dedupe

(dedupe
 [:clojure.core/none 1 2 3])
;;=&amp;gt; (1 2 3)
;; expected: (:clojure.core/none 1 2 3)

(dedupe
 [:clojure.core/none :clojure.core/none 1 2 3])
;;=&amp;gt; (1 2 3)
;; expected: (:clojure.core/none 1 2 3)

;; transducing arity is also affected
(sequence
 (dedupe)
 [:clojure.core/none 1 2 3])
;;=&amp;gt; (1 2 3)
;; expected: (:clojure.core/none 1 2 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;;;;; partition-by

(sequence (partition-by
           {0 0
            1 :clojure.core/none
            2 2})
          (range 3))
;;=&amp;gt; ([0] [1 2])
;; expected: ([0] [1] [2])

;; non-trasducing arity works OK:
(partition-by
 {0 0
  1 :clojure.core/none
  2 2}
 (range 3))
;;=&amp;gt; ((0) (1) (2))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Is this a conscious tradeoff for performance or is it something that might use a bit of additional thinking about better handling?&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11835/dedupe-and-partition-by-depending-on-magic-value</guid>
<pubDate>Thu, 28 Apr 2022 14:57:11 +0000</pubDate>
</item>
<item>
<title>What would transducers-first Clojure look like?</title>
<link>https://ask.clojure.org/index.php/11132/what-would-transducers-first-clojure-look-like</link>
<description>&lt;p&gt;Rich says in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/about/history&quot;&gt;History of Clojure&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;I think transducers are a fundamental primitive that decouples critical logic from list/sequence processing and construction, and if I had Clojure to do all over I would put them at the bottom.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This fascinates me, and I am really curious what would transducers-first Clojure look like? I don't really expect Rich to answer here (I should have asked this at his HOPL talk...) but perhaps someone who is closer to core might have some insight.&lt;/p&gt;
&lt;p&gt;I would love to see a Clojure where transducers are the default and &lt;em&gt;easiest&lt;/em&gt; way to solve things, where all the tutorials and gists and example code everywhere around would be using them and a context (vector, lazy, first etc.) was only chosen at the edges. Currently it is &lt;em&gt;easier&lt;/em&gt; (but perhaps not &lt;em&gt;simpler&lt;/em&gt;) to write lazy code than transducing code.&lt;/p&gt;
&lt;p&gt;I am wondering if transducers-first Clojure would address the above or would it mostly be about the plumbing behind a clojure.core similar to the current one.&lt;/p&gt;
&lt;p&gt;For my personal case, I actively have to fight laziness - I don't think I encountered a single place in our codebase where it would be beneficial but as it's still the easiest way of writing clojure I have to put in extra effort to not accidentally venture over to lazy land and to spot these patterns in PRs of others.&lt;/p&gt;
&lt;p&gt;I would love a clojure.core2 where transducers are the default, it's easy to write transducing code, potentially with less typing/ceremonies, the likes of comp and into [] etc. And stepping over to lazy land is always an opt-in thing, like the impure parts of clojure - stm, transients etc. I'm not entirely sure how a core library like that would look but it's something I'd love to try.&lt;/p&gt;
&lt;p&gt;Moreover, there are some transducer-specific optimisations like &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/cgrand/xforms#on-key-value-pairs&quot;&gt;https://github.com/cgrand/xforms#on-key-value-pairs&lt;/a&gt; that could be considered. And perhaps there could also be a way to use the multiple-coll arities of map as part of a transducer somehow.&lt;/p&gt;
&lt;p&gt;There could also be more baked-in support for an xform arg in functions that currently take a coll to preprocess them, like run! and str/join - if you actively use transducers you start to notice things like 'hey, I don't even need a collection there' and start to look for different transducing contexts - so instead of (count (into [] xform input)) you'd go (x/count xform input)&lt;/p&gt;
</description>
<category>Transducers</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11132/what-would-transducers-first-clojure-look-like</guid>
<pubDate>Sat, 02 Oct 2021 19:32:19 +0000</pubDate>
</item>
<item>
<title>halt-when transducer throws class cast exception when used with into</title>
<link>https://ask.clojure.org/index.php/10955/halt-when-transducer-throws-class-cast-exception-when-used</link>
<description>&lt;p&gt;The transducer halt-when throws an exception when used with into, but not with sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(sequence (halt-when #{4}) (range)) ;; =&amp;gt; (0 1 2 3)
(into [] (halt-when #{4}) (range))
;; class java.lang.Long cannot be cast to class clojure.lang.ITransientCollection (java.lang.Long is in module java.base of loader 'bootstrap'; clojure.lang.ITransientCollection is in unnamed module of loader 'app')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think that is caused by a bug where it's returning input instead of result, and I think this implementation should fix that specific issue:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn halt-when1
  ([pred] (halt-when1 pred nil))
  ([pred retf]
   (fn [rf]
     (fn
       ([] (rf))
       ([result]
        (if (and (map? result) (contains? result ::halt))
          (::halt result)
          (rf result)))
       ([result input]
        (if (pred input)
          (reduced {::halt (if retf (retf (rf result) input) (rf result))})
          (rf result input)))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, I think that the retf function is now coupled to the transducing context. So if you want to transform the result to, for example include the input that triggered the halt, then you need to know when you create the transducer that it will be used in a specific context and that you need to call conj, conj! or whatever. So I think that this signature of the function makes more sense:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn halt-when2
  ([pred] (halt-when2 pred nil))
  ([pred retf]
   (fn [rf]
     (fn
       ([] (rf))
       ([result]
        (if (and (map? result) (contains? result ::halt))
          (::halt result)
          (rf result)))
       ([result input]
        (if (pred input)
          (let [r (if retf
                    (retf rf result input)
                    result)]
            (reduced {::halt (rf r)}))
          (rf result input)))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which changes the signature of the retf function to accept the reducing function as well as the result and the input, and now you get to actually decide what to do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(into [] (halt-when2 #{4} (fn [rf r i] (rf r i))) (range)) ;; =&amp;gt; [0 1 2 3 4]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Could maybe add a third arity to halt-when with some options map to tell it if we'd passed in a 2 arity retf or a 3 arity one or something? Does that make sense? Or maybe I'm asking for a new thing called stop-at or something?&lt;/p&gt;
&lt;p&gt;--- edit ---&lt;/p&gt;
&lt;p&gt;Just found this &lt;a rel=&quot;nofollow&quot; href=&quot;https://groups.google.com/g/clojure/c/6HvmJIUsXKk/m/gLqUsfcnAwAJ&quot;&gt;https://groups.google.com/g/clojure/c/6HvmJIUsXKk/m/gLqUsfcnAwAJ&lt;/a&gt; which I think explains more the reasoning behind returning the input, but I still think it's useful to provide a strategy for transforming the result without needing to know what the actual reducing function is.&lt;/p&gt;
</description>
<category>Transducers</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10955/halt-when-transducer-throws-class-cast-exception-when-used</guid>
<pubDate>Thu, 19 Aug 2021 12:22:08 +0000</pubDate>
</item>
<item>
<title>&quot;concat&quot; two xforms into one?</title>
<link>https://ask.clojure.org/index.php/10108/concat-two-xforms-into-one</link>
<description>&lt;pre&gt;&lt;code&gt;(let [coll [{:a 1 :b 2}
            {:a 3 :b 4}
            {:a 7 :b 5}
            {:a 1 :b 4}]
      xf1 (comp (map :a) (filter #{1 3}))
      xf2 (comp (map :b) (filter #{2 4}))]
  (concat
    (into [] xf1 coll)
    (into [] xf2 coll)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;is there a way to combine the two xforms above (xf1 and xf2) into a single xform somehow so the collection coll will be traversed only once?&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10108/concat-two-xforms-into-one</guid>
<pubDate>Tue, 26 Jan 2021 21:57:14 +0000</pubDate>
</item>
<item>
<title>Why partition-by and partition-all have a transducer arity but partition does not?</title>
<link>https://ask.clojure.org/index.php/9829/partition-partition-have-transducer-arity-partition-does</link>
<description>&lt;p&gt;I couldn't find anything related in the Jira.&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9829/partition-partition-have-transducer-arity-partition-does</guid>
<pubDate>Thu, 19 Nov 2020 19:40:31 +0000</pubDate>
</item>
<item>
<title>Infinite loop with stateful transducer on core.async channel</title>
<link>https://ask.clojure.org/index.php/9529/infinite-loop-with-stateful-transducer-core-async-channel</link>
<description>&lt;p&gt;I am trying to implement a simple stateful transducer that counts the number of items (with ClojureScript):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn stateful-counter []
  (fn [xf]
    (let [counter (atom 0)]

      (fn
        ([] (xf))

        ([result]
         (xf (xf result @counter)))

        ([result _]
          (swap! counter inc)
          result)))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When running this on a sequence I get the output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(into [] (stateful-counter) (range 5))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[5]&lt;/p&gt;
&lt;p&gt;This is exactly what I expect.&lt;/p&gt;
&lt;p&gt;When running this on a core.async channel I get an infinite sequence of 5s:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(go (println
     (&amp;lt;! (let [c (async/chan 1 (stateful-counter))]

           (async/onto-chan! c (range 5))

           (async/into []
                       (async/take 10 c))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [5 5 5 5 5 5 5 5 5 5]&lt;/p&gt;
&lt;p&gt;If I don't use (async/take 10 _) there seems to be an infinite loop. The expected outcome would be [5].&lt;/p&gt;
&lt;p&gt;I have also tried using net.cgrand.xforms/count from &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/cgrand/xforms&quot;&gt;the xforms library&lt;/a&gt; and get the same unexpected result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(go (println
     (&amp;lt;! (let [c (async/chan 1 xforms/count)]

           (async/onto-chan! c (range 5))

           (async/into []
                       (async/take 10 c))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I was assuming that I made an implementation error in stateful-counter that caused the loop. But am confused that xforms/count produces the same (unexpected) result.&lt;/p&gt;
&lt;p&gt;This is a ClojureScript snippet, but I have been able to produce the same unexpected result with Clojure.&lt;/p&gt;
&lt;p&gt;Can somebody help me understand why applying the stateful transducer on a core.async channel results in an infinite sequence?&lt;/p&gt;
&lt;p&gt;EDIT: Same unexpected behavior seen with Clojure.&lt;/p&gt;
</description>
<category>Transducers</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9529/infinite-loop-with-stateful-transducer-core-async-channel</guid>
<pubDate>Sat, 08 Aug 2020 13:03:55 +0000</pubDate>
</item>
<item>
<title>How do sequences cache?</title>
<link>https://ask.clojure.org/index.php/9182/how-do-sequences-cache</link>
<description>&lt;p&gt;I have read that Clojure sequences &quot;cache&quot; their values as they are realized (&lt;a rel=&quot;nofollow&quot; href=&quot;https://insideclojure.org/2015/01/02/sequences/&quot;&gt;here&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/guides/faq#transducers_vs_seqs&quot;&gt;here&lt;/a&gt; for example). This often seems to come up when discussing the relative merits of using transducers for transforming values rather than chaining sequence functions, as the latter approach creates &quot;intermediate cached sequences&quot;.&lt;/p&gt;
&lt;p&gt;However, I have also come across the advice &quot;don’t hold on to your head&quot; when dealing with sequences, because holding a reference to the beginning of the sequence prevents GC from freeing up memory used to hold previously seen values in the sequence.&lt;/p&gt;
&lt;p&gt;At my current level of understanding these ideas appear to conflict. If sequences cache their results, then why does it matter whether you hold the head? Does caching not imply that all the realised elements are held onto anyway? Or looked at the other way, why would sequences cache their realised values if the GC is free to clean them up?&lt;/p&gt;
&lt;p&gt;I know I must be missing something obvious here, but I would really appreciate an explanation.&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9182/how-do-sequences-cache</guid>
<pubDate>Tue, 24 Mar 2020 17:55:31 +0000</pubDate>
</item>
</channel>
</rss>