Why does `get` behaves differently for accessing vector elements than using index as a parameter?


(get [1 2 3] 0) ; => 1

([1 2 3] 0) ;  => 1

(get [1 2 3] 10) ; => nil

([1 2 3] 10)

IndexOutOfBoundsException  clojure.lang.PersistentVector.arrayFor


Probably the last variant uses nth under the hood.


That makes sense, will confirm the source though. Thanks!


I think this is on purpose. I normally switch to using get when I explicitly don’t want exceptions thrown, but nil returned instead.

As get docstring says: Returns the value mapped to key, not-found or nil if key not present.

While yes, invoke on a Vector is implemented using nth: https://github.com/clojure/clojure/blob/e5fc803ff13f783661ef9491842719ab68a245ca/src/jvm/clojure/lang/APersistentVector.java#L291-L295

Whose docstring says: Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences.

But you know, maybe it was accidental. Cause its not consistent with Maps and Sets, which returns nil for both get and their invoke implementation, and actually uses get under the hood for their invoke call.


Vectors implement IFn, for invoke() of one argument, which they presume is an index and look up in themselves as if by nth, i.e. vectors are functions of their indices.

per https://clojure.org/reference/data_structures#Vectors