I'd like to know if there is a way to destructure a vector by index. Basically, a shorthand that would allow me to avoid:
(defn f [v]
(let [x (nth v 4)
y (nth v 5)]
(println x y)))
This is my basic problem:
user=> (defn f [{x 4 y 5}] (println x y))
#'user/f
user=> (f [0 1 2 3 4 5 6])
4 5
nil
user=> (f (apply vector (range 10)))
4 5
nil
user=> (f (range 10))
5 nil
nil
user=>
Vectors are associative, so you can use associative destructuring:
(let [{x 4 y 5} [0 1 2 3 4 5 6]]
[x y])
;= [4 5]
Responding to the comment below, this works everywhere any destructuring forms work, including in fn
parameter lists:
((fn [{x 4 y 5}] [x y]) [0 1 2 3 4 5 6])
;= [4 5]
If you pass a seq to a function defined as above in place of a vector, the rule for associative destructuring of seqs will be applied. Namely, the seq will first be poured into a hash map -- (range 10)
becomes {0 1 2 3 4 5 6 7 8 9}
at this stage -- and then this hash map will be destructured as a map.
There is no way of destructuring seqs by index. This is by design, as seqs are not meant for applications requiring fast random access.