David Shaked
David Shaked

Reputation: 3381

Why do vectors implement Associative?

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

Answers (2)

Carcigenicate
Carcigenicate

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

ClojureMostly
ClojureMostly

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

Related Questions