For context, started on Slack at https://clojurians.slack.com/archives/C03S1L9DN/p1650480331191719
This code works just fine on CLJ but fails with StackOverflowError on CLJS:
(def primes (remove
(fn [x]
(some #(zero? (mod x %)) primes))
(iterate inc 2)))
The vital difference between CLJ and CLJS in this case is that in the former, lazy-seq ends up wrapping its whole body in a function with ^:once.
The reasoning why it works that way is because in the code above, the inner primes is a closed over value, it becomes a local. When the body fn of a lazy-seq (the one with ^:once) is called the second time, its locals are nil, so that inner primes is also nil. And iteration stops.
In CLJS, there's no :once and no locals clearing, so the inner primes is never nil, and the execution keeps on going into that fn without even calling that zero?.
Even if the reasoning doesn't sound plausible, the hypothesis that it's indeed :once that's to blame for the difference can be easily confirmed by implementing lazy-seq in CLJ without :once and noticing that it leads to StackOverflowError.
It's unclear to me what to do in this case, but perhaps at least a note on the https://clojurescript.org/about/differences page should be made about it.