user=> (rseq [:a :b])
(:b :a)
user=> (rseq (rseq [:a :b]))
ClassCastException clojure.lang.APersistentVector$RSeq cannot be cast to
clojure.lang.Reversible clojure.core/rseq (core.clj:1532)
Why can't rseq
accept the result of a previous call to rseq
?
I read in the docstring that the argument has to be (actually, "can be") a vector or sorted-map, and the above shows that it can't be an RSeq
, so I already know that. What I want to know is: is there a good reason for this restriction? Is it just an oversight, or does this restriction provide some important benefit?
Also, is there a convenient workaround for this, other than just never calling rseq
? It's hard to know, when you return an RSeq
from one function, whether some other function somewhere else might call rseq
on it.
I'm asking because it's frustrating to see my code throw exceptions for such surprising reasons. If I knew why this made sense, I might be less likely to make this and similar kinds of errors.
You cannot call rseq
on a seq, since you need an input collection with constant-time random access to fullfill rseq
's constant-time performance characteristics, and seqs only provide efficient access (iteration) from the head down.
Calling rseq
on the result of rseq
cannot be special-cased to return the original collection since the original collection is never a seq. And if calling rseq
on a RSeq would return something (seq coll)
, that won't make it straightforward to support (rseq (drop x (rseq coll)))
. It's probably those kinds of complications that kept the language implementers from supporting "recursive" rseq at all.
If you need a general reversal function, use reverse
- which will be slower. If you can, you probably just want to keep a reference to (seq coll)
and (rseq coll)
if you need both.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With