Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why so many function in clojure have different behavior for list and vector and how it can be changed?

Tags:

clojure

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

1) What it is good for? I believe creator of clojure have very good reason to do this but I do not know it.

2) How can you make typesafe variant of those functions that will be act same way no matter data are in list or vector?

The function conj as it is defined have 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 function my-conj with following behavior

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

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

There are other function (cons, into, peek, pop) with same behavior so it would be nice if this construction could be easily adaptable to all of them.

like image 258
boucekv Avatar asked Jun 25 '13 06:06

boucekv


2 Answers

Because of the way the data structures are implemented it is more efficent to have them behave slightly differently. For example, it is easy to add an item at the start of a list (conceptually just link the item to the start of the existing list) but difficult to add an item at the start of a vector (conceptually moving the exiting items up an index) and vice versa.

The alternative would be a consistent conj but with a much worse worst case complexity.

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

like image 54
status203 Avatar answered Oct 08 '22 17:10

status203


On the surface, I understand how this can seem strange, but I think the idea is that conj does the default, simplest "add an element to this collection" action. Vectors and lists are built differently and require different kinds of default actions.

like image 45
skillet-thief Avatar answered Oct 08 '22 16:10

skillet-thief