<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent activity in Sequences</title>
<link>https://ask.clojure.org/index.php/activity/clojure/sequences</link>
<description></description>
<item>
<title>Edited: Destructuring {:as opts} unexpected behaviour with seq</title>
<link>https://ask.clojure.org/index.php/15028/destructuring-as-opts-unexpected-behaviour-with-seq?show=15028#q15028</link>
<description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I found out something weird in some old code, where I wanted to pass the first map in a sequence and by mistake the code was working while actually passing the sequence itself!&lt;/p&gt;
&lt;p&gt;After digging to make sense of this, I found out it has to do with the &lt;code&gt;{:as opts}&lt;/code&gt; destructuring.&lt;/p&gt;
&lt;p&gt;Here's some code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; even if something is assigned sequential vs associative
;; the `:as` is transparent
(let [[:as opts] {1 2 3 4}]
  opts)
#_=&amp;gt; {1 2, 3 4}
(let [{:as opts} [1 2 3 4]]
  opts)
#_=&amp;gt; [1 2 3 4]
;; however with a seq it's returned as a map
(let [{:as opts} (seq [1 2 3 4])]
  opts)
#_=&amp;gt; {1 2, 3 4}

;; and it only gets weirder!
(let [{:as opts} (seq [{:k :v}])]
  opts)
#_=&amp;gt; {:k :v}
(let [{:as opts} (seq [{:k1 :v1} {:k2 :v2}])]
  opts)
#_=&amp;gt; {{:k1 :v1} {:k2 :v2}}
(let [{:as opts} (seq [{:k1 :v1} {:k2 :v2} {:k3 :v3}])]
  opts)
#_=&amp;gt; {{:k1 :v1} {:k2 :v2}, :k3 :v3}
(let [{:as opts} (seq [{:k1 :v1} {:k2 :v2} :not-a-map])]
  opts)
;; java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword
(let [{:as opts} (seq [1 2 3])]
  opts)
;; java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In my case I didn't realize my code was wrong because &lt;code&gt;{:as opts} {:k :v}&lt;/code&gt; is the same as &lt;code&gt;{:as opts} (seq [{:k :v}])&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To me this is behaviour I would expect closer to &lt;code&gt;&amp;amp; {:as opts}&lt;/code&gt; rather than just plain map destructuring &lt;code&gt;{:as opts}&lt;/code&gt;. Maybe both behaviours should be separated?&lt;/p&gt;
&lt;p&gt;I think this should be tackled either by&lt;br&gt;
1. make &lt;code&gt;:as&lt;/code&gt; transparent regardless of what comes in to always bind&lt;br&gt;
2. throw an error earlier when it's not of the expected destructuring&lt;br&gt;
3. Document this very unexpected edge case in &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/reference/special_forms#associative-destructuring&quot;&gt;https://clojure.org/reference/special_forms#associative-destructuring&lt;/a&gt;&lt;br&gt;
4. Separate the keyword arguments use case from plain map destructuring? (Assuming both are now mixed together)&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/15028/destructuring-as-opts-unexpected-behaviour-with-seq?show=15028#q15028</guid>
<pubDate>Sun, 05 Apr 2026 09:19:47 +0000</pubDate>
</item>
<item>
<title>Answered: Optimized str function</title>
<link>https://ask.clojure.org/index.php/14990/optimized-str-function?show=15003#a15003</link>
<description>&lt;p&gt;I've done some &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/bsless/prrr&quot;&gt;independent exploration&lt;/a&gt; of the options space for optimizing &lt;code&gt;str&lt;/code&gt; which does not involve anything ground shattering but still gives good performance improvements&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;variadic arities (up to 20, yuck) will probably give the best performance. Can settle for common cases like up to 5  (apply str will still suck but whatever)&lt;/li&gt;
&lt;li&gt;using reduce instead of a loop (would probably require redefining str or providing a str1 with the old impl for bootstrap purposes)&lt;/li&gt;
&lt;li&gt;using inline meta, orthogonal to all other options&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, having a function like &lt;code&gt;str&lt;/code&gt; which only takes a sequence and reduces over it could provide a better code path than (apply str xs)&lt;/p&gt;
&lt;p&gt;Similar work has been done in &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/joinr/spork/blob/master/src/spork/util/general.clj#L835&quot;&gt;spork&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kumarshantanu/stringer&quot;&gt;stringer&lt;/a&gt;&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14990/optimized-str-function?show=15003#a15003</guid>
<pubDate>Sun, 29 Mar 2026 08:47:19 +0000</pubDate>
</item>
<item>
<title>Answer selected: seque forces n+2 items ahead of consumer instead of n</title>
<link>https://ask.clojure.org/index.php/14178/seque-forces-n-2-items-ahead-of-consumer-instead-of-n?show=14179#a14179</link>
<description>&lt;p&gt;Logged as &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2885&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2885&lt;/a&gt;&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14178/seque-forces-n-2-items-ahead-of-consumer-instead-of-n?show=14179#a14179</guid>
<pubDate>Wed, 09 Oct 2024 15:42:55 +0000</pubDate>
</item>
<item>
<title>Commented: `sequence` partially consumes input</title>
<link>https://ask.clojure.org/index.php/13155/sequence-partially-consumes-input?show=14168#c14168</link>
<description>This is extremely important to me as I want to be able to use `sequence` in order to handle consuming over potentially stateful sequence generators.&lt;br /&gt;
&lt;br /&gt;
In particular, I had to invent my own equivalent to `sequence` which did not eagerly consume the sequence in order to allow me to write a binary parsing library where multiple parsing functions consume different parts of the sequence, where any chunking or eager consumption would result in bad offsets and as a result an invalid parse of binary data.</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13155/sequence-partially-consumes-input?show=14168#c14168</guid>
<pubDate>Mon, 07 Oct 2024 15:24:51 +0000</pubDate>
</item>
<item>
<title>Commented: Suggested improvements to clojure.core/distinct</title>
<link>https://ask.clojure.org/index.php/14141/suggested-improvements-to-clojure-core-distinct?show=14158#c14158</link>
<description>For anyone who may be following this, I expanded the benchmarking, separating out the laziness change from the transducer variations. I also added a new variation for completeness.&lt;br /&gt;
&lt;br /&gt;
To be honest, the best performing functions surprised me. I did not expect the persistent set to perform as well as it did, and I also did not expect the transient variations to perform worse for large sequences. However, these both made sense when I considered the shape of the data (large sequences with a small percentage of unique values).&lt;br /&gt;
&lt;br /&gt;
I was also surprised that the transient set approach that skips the call to `contains?` performed as well as it did. While it avoids some of the code path of an earlier function, I am surprised that it didn't slow down similarly to the `distinct-transient` function.</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14141/suggested-improvements-to-clojure-core-distinct?show=14158#c14158</guid>
<pubDate>Tue, 01 Oct 2024 17:02:43 +0000</pubDate>
</item>
<item>
<title>Closed: `(nthrest nil n)` returns `nil` instead of `()`</title>
<link>https://ask.clojure.org/index.php/12098/nthrest-nil-n-returns-nil-instead-of?show=12098#q12098</link>
<description>&lt;p&gt;According to the documentation &lt;code&gt;nthrest&lt;/code&gt; should be equivalent to calling &lt;code&gt;rest&lt;/code&gt; repeatedly, but its behaviour differs when coll is &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I also noticed neither of the &lt;code&gt;nthrest&lt;/code&gt; and &lt;code&gt;nthnext&lt;/code&gt; functions are included in the test-nil-punning.&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12098/nthrest-nil-n-returns-nil-instead-of?show=12098#q12098</guid>
<pubDate>Thu, 23 May 2024 15:15:43 +0000</pubDate>
</item>
<item>
<title>Answered: How to map over a sequence of vectors?</title>
<link>https://ask.clojure.org/index.php/13535/how-to-map-over-a-sequence-of-vectors?show=13536#a13536</link>
<description>&lt;p&gt;You can turn that list of pairs (vectors) into a map with &lt;code&gt;(into {} ...)&lt;/code&gt; (which also lets you use transducers, check them out). And then you'll be able to use &lt;code&gt;update-vals&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;(map #('((first %) (second %))) input)&lt;/code&gt; throws&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The reader expands that &lt;code&gt;#(...)&lt;/code&gt; into &lt;code&gt;(fn* [p1__9#] ((quote ((first p1__9#) (second p1__9#)))))&lt;/code&gt; - you can check with &lt;code&gt;(macroexpand-1 '#(...))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The result of &lt;code&gt;(quote ...)&lt;/code&gt; there is a list, and then you're calling that list, which is where the exception comes from.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;(map #([(first %) (second %)]) input)&lt;/code&gt; makes the tooling complain&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A similar thing - &lt;code&gt;#(...)&lt;/code&gt; expands into something that immediately tries to call the result of &lt;code&gt;[...]&lt;/code&gt; as a function with no arguments.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;(map #(vector (first %) (second %)) input)&lt;/code&gt; throws &lt;code&gt;Execution error (ClassCastException)&lt;/code&gt; a couple of lines later&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Treating a map as a sequence gives you a sequence of kv-pairs with a type that implements &lt;code&gt;java.util.Map$Entry&lt;/code&gt;. The &lt;code&gt;keys&lt;/code&gt; function is supposed to be called on a map, not on a random sequence, and it just happens to work with a sequence of kv-pairs, but it expects for each pair to be a proper instance of that &lt;code&gt;Map$Entry&lt;/code&gt; interface.&lt;br&gt;
By using that &lt;code&gt;(vector ...)&lt;/code&gt; you're turning each map entry into a vector that doesn't implement that interface.&lt;/p&gt;
&lt;p&gt;Some generic advice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For kv-pairs, use &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;val&lt;/code&gt; instead of &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;second&lt;/code&gt; - they also expect a map entry and will fail much earlier if something's wrong, making figuring stuff out easier. They're also faster and more indicative what the code's intent&lt;/li&gt;
&lt;li&gt;If you have problems with &lt;code&gt;#(...)&lt;/code&gt;, try writing it as &lt;code&gt;(fn [...] ...)&lt;/code&gt; with properly named arguments (so e.g. not &lt;code&gt;x&lt;/code&gt; but &lt;code&gt;kv-pair&lt;/code&gt; - doesn't sound like much but helps with figuring stuff out if you're stuck)&lt;/li&gt;
&lt;li&gt;If you have &lt;code&gt;ClassCastException&lt;/code&gt;, carefully read the docs of the functions that you're calling&lt;/li&gt;
&lt;li&gt;When you see an exception, study its stacktrace and try to figure out what exactly went wrong. Might be hard at first but will become a breeze later, at least in most cases&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13535/how-to-map-over-a-sequence-of-vectors?show=13536#a13536</guid>
<pubDate>Sun, 10 Dec 2023 10:22:26 +0000</pubDate>
</item>
<item>
<title>Commented: clojure.lang.LazySeq synchronized methods pin virtual thread</title>
<link>https://ask.clojure.org/index.php/13318/clojure-lang-lazyseq-synchronized-methods-virtual-thread?show=13335#c13335</link>
<description>Thanks for your attention, Alex!&lt;br /&gt;
I guess my banal scenarioses will just bring noise to already clarified &amp;quot;Request to find and eliminate virtual thread pinning&amp;quot; issue:&lt;br /&gt;
- blocking IO call from function called from clojure.core/map&lt;br /&gt;
- blocking IO call from clojure.core/deref&lt;br /&gt;
&lt;br /&gt;
Thanks!</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13318/clojure-lang-lazyseq-synchronized-methods-virtual-thread?show=13335#c13335</guid>
<pubDate>Wed, 27 Sep 2023 12:05:34 +0000</pubDate>
</item>
<item>
<title>Commented: distinct should support sets</title>
<link>https://ask.clojure.org/index.php/9010/distinct-should-support-sets?show=13228#c13228</link>
<description>This should be fixed since the transducer version works fine and so behaves differently.&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
(into [] (distinct) #{:a :b})&lt;br /&gt;
=&amp;gt; [:b :a]&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The regular distinct implementation chooses to use destructuring which needs nth.&lt;br /&gt;
&lt;br /&gt;
And yes, we also have some util functions that take `coll` and are expected to work across all types of coll.</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9010/distinct-should-support-sets?show=13228#c13228</guid>
<pubDate>Mon, 28 Aug 2023 17:42:06 +0000</pubDate>
</item>
<item>
<title>Answer selected: Infinite lazy sequence expands until JVM runs out of memory</title>
<link>https://ask.clojure.org/index.php/13111/infinite-lazy-sequence-expands-until-jvm-runs-out-of-memory?show=13113#a13113</link>
<description>&lt;p&gt;I suspect your problem is that you are &quot;holding onto the head&quot; -- your function binds &lt;code&gt;lazy-primes&lt;/code&gt; to the sequence and then you walk down the sequence so you still have a reference to the entire sequence, and if you ask for a large enough &lt;code&gt;num&lt;/code&gt;, you are going to exceed the heap since your function needs the entire sequence to work.&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13111/infinite-lazy-sequence-expands-until-jvm-runs-out-of-memory?show=13113#a13113</guid>
<pubDate>Sun, 30 Jul 2023 18:20:58 +0000</pubDate>
</item>
<item>
<title>Retagged: Add interleave-all (like partition-all is to partition)</title>
<link>https://ask.clojure.org/index.php/12125/add-interleave-all-like-partition-all-is-to-partition?show=12125#q12125</link>
<description>&lt;p&gt;At work we have some situations where we need to interleave lazy sequences in such a way that if one sequence is shorter than the other we want elements from the longer sequence to be concatenated after the interleaving runs out of the shorter sequence(s).&lt;/p&gt;
&lt;p&gt;The following code could be used -- a slight variant of the existing &lt;code&gt;interleave&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn interleave-all
  &quot;Like interleave, but stops when the longest seq is done, instead of
   the shortest.&quot;
  {:copyright &quot;Rich Hickey, since this is a modified version of interleave&quot;}
  ([] ())
  ([c1] (lazy-seq c1))
  ([c1 c2]
   (lazy-seq
    (let [s1 (seq c1) s2 (seq c2)]
      (cond
       (and s1 s2) ; there are elements left in both
       (cons (first s1) (cons (first s2)
                              (interleave-all (rest s1) (rest s2))))
       s1 ; s2 is done
       s1
       s2 ; s1 is done
       s2))))
  ([c1 c2 &amp;amp; colls]
   (lazy-seq
    (let [ss (filter identity (map seq (conj colls c2 c1)))]
      (concat (map first ss) (apply interleave-all (map rest ss)))))))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12125/add-interleave-all-like-partition-all-is-to-partition?show=12125#q12125</guid>
<pubDate>Tue, 18 Jul 2023 13:33:11 +0000</pubDate>
</item>
<item>
<title>Answered: Is there a version of `range` that includes the end argument?</title>
<link>https://ask.clojure.org/index.php/13013/is-there-a-version-of-range-that-includes-the-end-argument?show=13026#a13026</link>
<description>&lt;p&gt;I often need something like this and so wrote &lt;a rel=&quot;nofollow&quot; href=&quot;https://cljdoc.org/d/tupelo/tupelo/23.05.31/api/tupelo.core#thru&quot;&gt;the &lt;code&gt;thru&lt;/code&gt; function&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;`&lt;/code&gt;&lt;br&gt;
tupelo.core/thru&lt;/p&gt;
&lt;p&gt;(thru end)&lt;br&gt;
(thru start end)&lt;br&gt;
(thru start end step)&lt;/p&gt;
&lt;p&gt;Returns a sequence of numbers. Like clojure.core/rng, but is inclusive of the right boundary value. Not lazy.&lt;br&gt;
&lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13013/is-there-a-version-of-range-that-includes-the-end-argument?show=13026#a13026</guid>
<pubDate>Tue, 20 Jun 2023 21:33:58 +0000</pubDate>
</item>
<item>
<title>Commented: Performance improvements to creation of small vectors with TransientVector</title>
<link>https://ask.clojure.org/index.php/13009/performance-improvements-creation-vectors-transientvector?show=13024#c13024</link>
<description>Indeed, a raw patch is not the most human-friendly thing to look at in the browser. When viewed locally, most editors will at least colorize the changes, but you still can't navigate it as well as a git commit within the repo.&lt;br /&gt;
&lt;br /&gt;
The thing is, sending patches is the only accepted workflow for contributing code to Clojure. That is why you'll see those Jira tickets with patches attached and no PRs on Github.&lt;br /&gt;
&lt;br /&gt;
Anyway, here is my commit on Github: &lt;a href=&quot;https://github.com/alexander-yakushev/clojure/commit/9d12dec06e4a9e0ec21e1b43741dc7d6adafc45e&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/alexander-yakushev/clojure/commit/9d12dec06e4a9e0ec21e1b43741dc7d6adafc45e&lt;/a&gt;</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13009/performance-improvements-creation-vectors-transientvector?show=13024#c13024</guid>
<pubDate>Mon, 19 Jun 2023 20:22:28 +0000</pubDate>
</item>
<item>
<title>Edited: Run a task parallely to delete tags</title>
<link>https://ask.clojure.org/index.php/12999/run-a-task-parallely-to-delete-tags?show=12999#q12999</link>
<description>&lt;pre&gt;&lt;code&gt;(defn- find-story-ids-by-tag [tag-id]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  (map :id (db-content-tag/read-contents-by-tag-id (config/db-spec) tag-id)))&lt;/p&gt;
&lt;p&gt;(defn- update-story [txn publisher-id story-id tag-id]&lt;br&gt;
  (let [{:keys [published-json]} (db-content/find-by-id txn story-id)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    updated-tags (filter (fn [tag] (not= (:id tag) tag-id)) (:tags published-json))
    _ (db-story/update-published-json-without-timestamps txn publisher-id story-id (assoc published-json :tags updated-tags))]
(log/info {:message &quot;[TAG-DELETION] Updated Story Tags in Published JSON&quot;
           :publisher-id publisher-id
           :tag-id tag-id
           :story-id story-id
           :updated-tags-json updated-tags})))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(defn- delete-tag [publisher-id tag-id]&lt;br&gt;
  (let [associated-content-ids (find-story-ids-by-tag tag-id)]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(transaction/with-transaction
  [txn (config/db-spec)]
  (do
    (when (seq associated-content-ids)
      (do
        (doseq [story-id associated-content-ids]
          (update-story txn publisher-id story-id tag-id))
        (db-content-tag/delete-batch-by-tag txn tag-id associated-content-ids)
        (log/info {:message &quot;[TAG-DELETION] Deleted from Content Tag&quot;
                   :publisher-id publisher-id
                   :tag-id tag-id
                   :story-ids associated-content-ids})))
    (db-tag/delete txn publisher-id tag-id)
    (log/info {:message &quot;[TAG-DELETION] Deleted Tag&quot;
               :publisher-id publisher-id
               :tag-id tag-id})))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(defn run [publisher-id tag-ids]&lt;br&gt;
  (comment run 123 [4 5 6])&lt;br&gt;
  (try&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(do
  (log/info {:message &quot;[TAG-DELETION] started&quot;
             :publisher-id publisher-id
             :tag-ids tag-ids})
  (doseq [tag-id tag-ids] (if (db-tag/find-by-id (config/db-spec) publisher-id tag-id)
                            (delete-tag publisher-id tag-id)
                            (log/info {:message &quot;[TAG-DELETION] Tag Not Found&quot;
                                       :publisher-id publisher-id
                                       :tag-id tag-id})))
  (log/info {:message &quot;[TAG-DELETION] completed&quot;
             :publisher-id publisher-id
             :tag-ids tag-ids}))
(catch Exception e
  (log/exception e {:message &quot;[TAG-DELETION] errored&quot;
                    :publisher-id publisher-id
                    :tag-ids tag-ids}))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I have less than 100 tags this works, but say I have 100 000 tags it is very time consuming. How to modify this code which can run in parallel and takes less time? Currently the task uses seq for both deleting and updating the story&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12999/run-a-task-parallely-to-delete-tags?show=12999#q12999</guid>
<pubDate>Mon, 05 Jun 2023 05:36:51 +0000</pubDate>
</item>
<item>
<title>Edited: Why do r/foldcat return types give inconsistent results when passed directly to `vec`?</title>
<link>https://ask.clojure.org/index.php/12984/foldcat-return-types-inconsistent-results-passed-directly?show=12984#q12984</link>
<description>&lt;p&gt;When using reducers, I will occasionally use foldcat to &quot;realize&quot; the transformed collection through the reducer chain. For downstream code, its preferable to have a fully realized standard clojure collection like &lt;code&gt;vec&lt;/code&gt;. This is often the case when updating core collection code to use reducers for performance reasons:&lt;/p&gt;
&lt;p&gt;Note the following works just fine:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(-&amp;gt;&amp;gt; (repeat 2 3) (vec) (r/map inc) (r/foldcat) (vec))
=&amp;gt; [4 4]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the input gets large enough however, this triggers the parallel behavior which changes the return type from Array to Cat and causes the last &lt;code&gt;vec&lt;/code&gt; to choke:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(-&amp;gt;&amp;gt; (repeat 513 3) (vec) (r/map inc) (r/foldcat) (vec))
Execution error at user/eval19976 (form-init6687476487684153971.clj:1).
Unable to convert: class clojure.core.reducers.Cat to Object[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I surmise that the &quot;correct&quot; way to do this is to use &lt;code&gt;(into [])&lt;/code&gt; instead of &lt;code&gt;vec&lt;/code&gt; in the last position which works just fine.&lt;/p&gt;
&lt;p&gt;That said, this came as fairly surprising behavior given that &lt;code&gt;seq&lt;/code&gt; and &lt;code&gt;into&lt;/code&gt; work just fine on both &lt;code&gt;Array&lt;/code&gt; and &lt;code&gt;Cat&lt;/code&gt;. Its also quite dangerous because such code can function quietly in production until the input data grows passed a certain threshold. Is there pragmatic reason that &lt;code&gt;seq&lt;/code&gt; works for &lt;code&gt;Cat&lt;/code&gt; but &lt;code&gt;vec&lt;/code&gt; doesn't?&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12984/foldcat-return-types-inconsistent-results-passed-directly?show=12984#q12984</guid>
<pubDate>Wed, 31 May 2023 03:28:13 +0000</pubDate>
</item>
<item>
<title>Answered: Partitioning a list based on comparing the elements within the list</title>
<link>https://ask.clojure.org/index.php/9450/partitioning-list-based-comparing-the-elements-within-list?show=12923#a12923</link>
<description>&lt;p&gt;The library dev.weavejester/medley (&quot;A small collection of useful, mostly pure functions that might not look out of place in the clojure.core namespace&quot;) contains &lt;code&gt;partition-between&lt;/code&gt; since 1.7.0. That function can be used to partition a sorted list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require '[medley.core :refer [partition-between]])

(partition-between (fn [x y] (&amp;gt; y (inc x))) [1 2 3 7 8 14 15 16 17 20 21 22])
;; =&amp;gt; ((1 2 3) (7 8) (14 15 16 17) (20 21 22))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9450/partitioning-list-based-comparing-the-elements-within-list?show=12923#a12923</guid>
<pubDate>Mon, 08 May 2023 08:25:25 +0000</pubDate>
</item>
<item>
<title>Commented: Use transducers on clojure.core lazy sequence transformations</title>
<link>https://ask.clojure.org/index.php/12847/use-transducers-clojure-core-lazy-sequence-transformations?show=12850#c12850</link>
<description>Clarification from Alex on Slack:&lt;br /&gt;
&lt;br /&gt;
&amp;gt; I was really referring to reduce in that sentence&lt;br /&gt;
&amp;gt; it [eduction] is delayed&lt;br /&gt;
&amp;gt; it is often used in eager scenarios&lt;br /&gt;
&amp;gt; it's iterator based, but often used with reduce, which is eager&lt;br /&gt;
&lt;br /&gt;
More details in the thread at &lt;a href=&quot;https://clojurians.slack.com/archives/C03S1KBA2/p1681394119498109?thread_ts=1681383034.191669&amp;amp;cid=C03S1KBA2&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojurians.slack.com/archives/C03S1KBA2/p1681394119498109?thread_ts=1681383034.191669&amp;amp;cid=C03S1KBA2&lt;/a&gt;</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12847/use-transducers-clojure-core-lazy-sequence-transformations?show=12850#c12850</guid>
<pubDate>Thu, 13 Apr 2023 16:59:10 +0000</pubDate>
</item>
<item>
<title>Commented: Tree recursion in Clojure</title>
<link>https://ask.clojure.org/index.php/11916/tree-recursion-in-clojure?show=12841#c12841</link>
<description>You should be able `loop/recur` if you keep a stack in your loop onto which you push things that you need to visit later? That's basically what you do with recursion?</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11916/tree-recursion-in-clojure?show=12841#c12841</guid>
<pubDate>Wed, 05 Apr 2023 20:01:23 +0000</pubDate>
</item>
<item>
<title>Answer selected: find on seqs</title>
<link>https://ask.clojure.org/index.php/11830/find-on-seqs?show=11831#a11831</link>
<description>&lt;p&gt;It has been discussed and rejected before &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2056&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2056&lt;/a&gt;&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11830/find-on-seqs?show=11831#a11831</guid>
<pubDate>Thu, 28 Apr 2022 09:28:54 +0000</pubDate>
</item>
<item>
<title>Answered: Calling str on lazy-seq and eductions has confusing semantics</title>
<link>https://ask.clojure.org/index.php/10032/calling-str-lazy-seq-and-eductions-has-confusing-semantics?show=10873#a10873</link>
<description>&lt;p&gt;Logged as &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2647&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2647&lt;/a&gt;&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10032/calling-str-lazy-seq-and-eductions-has-confusing-semantics?show=10873#a10873</guid>
<pubDate>Thu, 29 Jul 2021 00:30:14 +0000</pubDate>
</item>
<item>
<title>Answer edited: Why does partition-by iterates over elements more than once?</title>
<link>https://ask.clojure.org/index.php/10573/why-does-partition-by-iterates-over-elements-more-than-once?show=10574#a10574</link>
<description>&lt;pre&gt;&lt;code&gt;([f coll]
 (lazy-seq
  (when-let [s (seq coll)]
    (let [fst (first s)
          fv (f fst)
          run (cons fst (take-while #(= fv (f %)) (next s)))]
      (cons run (partition-by f (lazy-seq (drop (count run) s))))))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looks like &lt;code&gt;f&lt;/code&gt; gets called 1x when binding &lt;code&gt;fv&lt;/code&gt;.  Since the &lt;code&gt;take-while&lt;/code&gt; portion doesn't yield any similar keys, the value of &lt;code&gt;run&lt;/code&gt; is '(1).  However, &lt;code&gt;f&lt;/code&gt; &quot;was&quot; invoked on the first value of the rest of s, so 2 gets printed 1 time.  When &lt;code&gt;partition-by&lt;/code&gt; pseudo recurses during the lazy-seq construction, the first arg of the new partition is now 2.  &lt;code&gt;fv&lt;/code&gt; is determined by invoking &lt;code&gt;f&lt;/code&gt; on 2, which prints two, etc.  The process repeats.&lt;/p&gt;
&lt;p&gt;The transducer variant never passes the head of the next partition recursively, so it only ever calls &lt;code&gt;f&lt;/code&gt; once per element of the original input.&lt;/p&gt;
&lt;p&gt;Note: we can derive a 1-time partition function variant without state like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;user&amp;gt; (defn partition-by-once [f coll]
        (-&amp;gt;&amp;gt; coll
             (map (fn [x] [(f x) x]))
             (partition-by first)
             (map #(map second %))))
#'user/partition-by-once
user&amp;gt; (partition-by-once #(do (println %)
                               (rand)) [1 2 3])
1
2
3
((1) (2) (3))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can do the volatile trick that the transducer uses to get an implementation too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    (defn partition-by-once-statefully
      [f coll]
      (let [pv   (volatile! ::none)
            test (fn [v] (vreset! pv (f v)))
            aux  (fn aux
                   ([coll]
                    (lazy-seq
                     (when-let [s (seq coll)]
                       (let [fst (first coll)
                             fv  @pv
                             run (cons fst (take-while #(= fv (test %)) (next s)))]
                         (cons run (aux (lazy-seq (drop (count run) s))))))))
                  ([fst remaining]
                   (if-let [s (seq remaining)]
                     (let [fv  (test fst)
                           run (cons fst (take-while #(= fv (test %)) s))]
                       (cons run (aux (lazy-seq (drop (dec (count run)) s)))))
                     `((~fst)))))]
        (when-let [s (seq coll)]
          (aux  (first coll) (next coll)))))

    user&amp;gt; (doall (partition-by-once-vol (fn [v] (println v) (odd? v)) [1 2 3 5 7 8 10 11]))
    1
    2
    3
    5
    7
    8
    10
    11
    ((1) (2) (3 5 7) (8 10) (11))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10573/why-does-partition-by-iterates-over-elements-more-than-once?show=10574#a10574</guid>
<pubDate>Sat, 08 May 2021 09:39:51 +0000</pubDate>
</item>
<item>
<title>Commented: Does def hold onto the head?</title>
<link>https://ask.clojure.org/index.php/10237/does-def-hold-onto-the-head?show=10241#c10241</link>
<description>ah, the issue is nth is being inline expanded to a static method call instead of a function call, and the reflective static method call the interpreter does doesn't attempt to avoid holding the head.</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10237/does-def-hold-onto-the-head?show=10241#c10241</guid>
<pubDate>Wed, 24 Feb 2021 00:11:01 +0000</pubDate>
</item>
<item>
<title>Commented: Suspected bug in `clojure.core/partition`</title>
<link>https://ask.clojure.org/index.php/9937/suspected-bug-in-clojure-core-partition?show=9986#c9986</link>
<description>The `step` parameter isn't relevant to the described behavior: (partition n coll) just means (partition n n coll), i.e., partition with a step of n, so it _always_ has a step value and that just determines how many elements are skipped in coll before starting the next partition. What Alex has described as the behavior is not affected by the step value.&lt;br /&gt;
&lt;br /&gt;
The pad collection only matters if the last partition that would be generated doesn't have n items in it:&lt;br /&gt;
&lt;br /&gt;
dev=&amp;gt; (partition 3 3 [:a :b :c] (range 5))&lt;br /&gt;
&lt;br /&gt;
((0 1 2) (3 4 :a))&lt;br /&gt;
&lt;br /&gt;
dev=&amp;gt; (partition 3 3 (range 5))&lt;br /&gt;
&lt;br /&gt;
((0 1 2))&lt;br /&gt;
&lt;br /&gt;
dev=&amp;gt; (partition 3 2 [:a :b :c] (range 5))&lt;br /&gt;
&lt;br /&gt;
((0 1 2) (2 3 4) (4 :a :b))&lt;br /&gt;
&lt;br /&gt;
dev=&amp;gt; (partition 3 2 (range 5))&lt;br /&gt;
&lt;br /&gt;
((0 1 2) (2 3 4))&lt;br /&gt;
&lt;br /&gt;
dev=&amp;gt; (partition 3 1 [:a :b :c] (range 5))&lt;br /&gt;
&lt;br /&gt;
((0 1 2) (1 2 3) (2 3 4) (3 4 :a))&lt;br /&gt;
&lt;br /&gt;
dev=&amp;gt; (partition 3 1 (range 5))&lt;br /&gt;
&lt;br /&gt;
((0 1 2) (1 2 3) (2 3 4))</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9937/suspected-bug-in-clojure-core-partition?show=9986#c9986</guid>
<pubDate>Tue, 29 Dec 2020 22:05:22 +0000</pubDate>
</item>
<item>
<title>Commented: Why is r/fold not parallelized across all available cpus?</title>
<link>https://ask.clojure.org/index.php/9475/why-is-r-fold-not-parallelized-across-all-available-cpus?show=9485#c9485</link>
<description>Got it. That makes sense, and is a cool example of the streaming possibilities of `clojure.data.csv`. This machine has 32GB of ram, so I was able to amend my code to write out 100M row csv and nippy datasets. The csv on disk is ~658MB and the nippy is ~537MB. The csv dataset loads in ~47s and the nippy dataset loads in ~2.8s. (:</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9475/why-is-r-fold-not-parallelized-across-all-available-cpus?show=9485#c9485</guid>
<pubDate>Mon, 20 Jul 2020 21:07:20 +0000</pubDate>
</item>
<item>
<title>Answered: On the realization of lazy-seqs which throw exceptions</title>
<link>https://ask.clojure.org/index.php/9326/on-the-realization-of-lazy-seqs-which-throw-exceptions?show=9327#a9327</link>
<description>&lt;p&gt;Variants of this have been discussed in the past. The general advice is: we don't make any guarantees about what happens if lazy seqs throw on realization. If you're doing side effect-y things in your lazy seq, consider using run!, loop/recur, etc.&lt;/p&gt;
&lt;p&gt;See  &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-2069&quot;&gt;https://clojure.atlassian.net/browse/CLJ-2069&lt;/a&gt; for a similar ticket.&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9326/on-the-realization-of-lazy-seqs-which-throw-exceptions?show=9327#a9327</guid>
<pubDate>Mon, 25 May 2020 15:13:15 +0000</pubDate>
</item>
<item>
<title>Answer edited: Duplicated `next` before `recur`?</title>
<link>https://ask.clojure.org/index.php/9075/duplicated-next-before-recur?show=9090#a9090</link>
<description>&lt;p&gt;Could it be the order in which functions are defined in core?&lt;/p&gt;
&lt;p&gt;Skimming through core.clj the &lt;code&gt;if-let&lt;/code&gt; macro is actually defined at line 1841:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/clj/clojure/core.clj#L1841&quot;&gt;https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/clj/clojure/core.clj#L1841&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;while the &quot;next more recur next more&quot; fragments (in math stuff) are used before &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;if-let&lt;/code&gt; exists (line 1055):&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/clj/clojure/core.clj#L1055&quot;&gt;https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/clj/clojure/core.clj#L1055&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Code after &lt;code&gt;defmacro if-let&lt;/code&gt; is actually using the pattern you expect (line 3690):&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/clj/clojure/core.clj#L3690&quot;&gt;https://github.com/clojure/clojure/blob/653b8465845a78ef7543e0a250078eea2d56b659/src/clj/clojure/core.clj#L3690&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I think there is the regular single pass compilation with core.clj as with regular clojure code. Functions have to be defined before you can use them, both macros and defns.&lt;/p&gt;
&lt;p&gt;I am not sure why the order have to be like this, maybe something with bootstrapping.&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9075/duplicated-next-before-recur?show=9090#a9090</guid>
<pubDate>Tue, 11 Feb 2020 11:32:30 +0000</pubDate>
</item>
<item>
<title>Comment edited: changing some?</title>
<link>https://ask.clojure.org/index.php/8361/changing-some?show=8663#c8663</link>
<description>I agree with Andy that having a real-time discussion on Slack may be a lot more productive since right now it sounds like you can't even articulate any specific questions to help remove any confusion?</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/8361/changing-some?show=8663#c8663</guid>
<pubDate>Thu, 26 Sep 2019 18:45:52 +0000</pubDate>
</item>
<item>
<title>Answered: pmap - hard wired level of parallelism</title>
<link>https://ask.clojure.org/index.php/8396/pmap-hard-wired-level-of-parallelism?show=8428#a8428</link>
<description>&lt;p&gt;As Sean said pmap is a quick-and-dirty mechanism which you should generally avoid.&lt;br&gt;
People often recommend using java Executors framework instead (via interop).&lt;br&gt;
There's also an alternative implementation of pmap (and other concurrency constructs in &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/TheClimateCorporation/claypoole&quot;&gt;https://github.com/TheClimateCorporation/claypoole&lt;/a&gt; where you can specify your own thread pool.&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/8396/pmap-hard-wired-level-of-parallelism?show=8428#a8428</guid>
<pubDate>Fri, 16 Aug 2019 04:41:06 +0000</pubDate>
</item>
</channel>
</rss>