Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

Indexing a vector with other integer types works fine, only indexing with a short int gives the wrong result:

`
(get [1 2] (int 1))

=> 2

(get [1 2] (bigint 1))

=> 2

(get [1 2] (long 1))

=> 2

(get [1 2] (short 1))

=> nil

`

Is this a bug? If not, why?

1 Answer

+1 vote
by

It also returns nil if you use a type byte as the index, not only for short.

The reason this happens is that in the method valAt in Clojure's source file APersistentVector.java, used to look up values in Clojure's PersistentVector class, calls a method isInteger in package clojure.lang.Util to determine whether the index is an integer type or not. That method returns true if its argument is of class java.lang.Integer, java.lang.Long, clojure.lang.BigInt, or java.math.BigInteger, but false for any other types.

I do not know if this is considered a bug, or more likely, a design decision to handle the most common cases (java.lang.Long is the default integer type in Clojure) quickly in this hot code path.

by
I do not consider it a bug. shorts are not considered to be one of Clojure's numeric types (but some support exists for interop).
by
@alexdmiller

What is the reason for that? For bytes it's clear (they store data), but not for shorts. Also '(int? (short 1))' returns true.
by
As I said, "shorts are not considered to be one of Clojure's numeric types".
by
Or maybe you're asking why shorts are not considered to be part of that - Clojure focuses on 64-bit numeric types - defaults are longs and doubles. Arbitrary precision variants are provided above that BigInt/BigDecimal. Because reasons, both java BigIntegers and Clojure's own BigInt variant are supported (the latter works as longs while in range so this is kind of a perf thing). Integers and shorts are supported primarily for interop.
...