Hacker News new | past | comments | ask | show | jobs | submit login

> 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.



For 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).


Not 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.


Interestingly, im-rs for Rust offers better than linear performance when inserting at either end: https://docs.rs/im/15.0.0/im/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: