3 ms·
> vectors can easily be extended (on either end!) functionally It's true that you can extend a vector on either end user=> (def xs [2 3]) #'user/xs
by loevborg 6y ago
> vectors can easily be extended (on either end!) functionally
It's true that you can extend a vector on either end
user=> (def xs [2 3])
#'user/xs
user=> (conj xs 4)
[2 3 4]
user=> (into [1] xs)
[1 2 3]
but only the first operation will be O(1). The second operation is O(n) and should be avoided in hot loops.
- hawkice 6y agoFor future readers: if you want to do this, I would first just accumulate into the seq backwards and reverse it into a vec. If that wasn't enough, use transients. Not _that_ different from other languages -- if you want to do something, and the obvious way is slow, (reverse (accumulate (reverse (map reverse vecs)))) is the obvious workaround for asymmetric performance (although I've not had this issue personally).
- loevborg 6y agoNot sure I understand your comment. Is `accumulate` a scheme function? My comment was intended to say that Clojure vectors have some operations that are performant and some that aren't. It is part of Clojure's philosophy to encourage the operations that are natural for the respective data type. `conj` appends to the end when applied to a vector but inserts at the head when applied to a list. So you want to pick the appropriate data structure for the job and make sure only natural operations are used. For a vector appending is natural whereas inserting at the head is not.
- fnordsensei 6y agoInterestingly, im-rs for Rust offers better than linear performance when inserting at either end: https://docs.rs/im/15.0.0/im/ https://docs.rs/im/15.0.0/im/