Why do so many functions in clojure have different behavior for list and vector and how can I change it?

In clojure, you have several functions that act differently for a vector and for a list. I have two questions.

1) What is it useful for? I believe that the creator of clojure has a very good reason for this, but I do not know.

2) How can you make a typical version of these functions that will act the same way, regardless of whether the data is in a list or a vector?

The conj function, as defined, has the following behavior

(conj [1 2 3] 4) [1 2 3 4] (conj '(1 2 3) 4) (4 1 2 3) 

I would like to have a my-conj function with the following behavior

 (my-conj [1 2 3] 4) [1 2 3 4] (my-conj '(1 2 3) 4) (1 2 3 4) 

There is another function (cons, to, peek, pop) with the same behavior, so it would be nice if this design could easily adapt to all of them.

+6
source share
2 answers

Due to the way data structures are implemented, it is more efficient to behave somewhat differently. For example, it’s easy to add an element at the beginning of the list (conceptually just linking the element to the beginning of the existing list), but it’s difficult to add an element at the beginning of the vector (conceptually moving the output elements up the index) and vice versa.

An alternative would be a consistent match, but with much worse complexity in the worst case.

(see http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html for a table of performance guarantees)

+9
source

At first glance, I understand how strange this may seem, but I think the idea is that conj does the default, simplest action "add an element to this collection." Vectors and lists are built differently and require different actions by default.

+3
source

Source: https://habr.com/ru/post/948037/


All Articles