Reputation: 3381
I was surprised to discover that clojure
vectors implement the Associative interface.
(associative? [1 2 3]) ; => true
I assume this interface provides optimized indexing by keys. Following this assumption, the interface seems appropriate for map data structures, but odd for vectors, which don't follow a key-value heuristic in my mind.
Is my mental model for Associative
or vector
's implementation incorrect? What purpose does this design choice serve?
Upvotes: 3
Views: 371
Reputation: 45741
It may not seem intuitive initially, but vectors are keyed by their indices, which allow them to make use of all the standard associative functions. This makes it very easy to do simple operations on them:
(def v [1 2 3])
(assoc v 1 4)
[1 4 3]
(update v 1 inc)
[1 3 3]
(get v 1) ; The same as (v 1)
2
Or, if you have a 2D vector:
(def v [[1 2 3]
[4 5 6]
[7 8 9]])
(assoc-in v [2 1] 0)
[[1 2 3]
[4 5 6]
[7 0 9]]
Without this design choice, an entire separate set of functions would need to be created and used specifically for vectors. Having a standardized interface allows you to write functions that don't care about specifically what structure they're working on.
Think about it this way: Say you wanted to write a function that "replaces" an element of a vector. Would its signature be any different from the existing assoc
function; besides specifically expecting a vector?
Upvotes: 10
Reputation: 4713
Clojure vectors associate an index with a value. This means you can do things like this:
(assoc [0 1] 0 2)
(reduce-kv (fn [m idx v]
(assoc m idx v)) {} [0 1 2])
And both are efficient.
Upvotes: 4