I’m not sure if the API always strictly adheres to it, but there is a type alias Dims for Tuple{Vararg{Int, N}} where N used for AbstractArray dimensions. Some functions like zeros accept dims arguments with more integer types, but even then it gets wrangled into Dims for the output:
julia> typeof(size(zeros(Float64, (UInt32(4), 10)))) # 64-bit system
Tuple{Int64, Int64}
On v1.10.2, all the Base methods for rand appear to annotate dims with ::Integer... or ::Dims. So, rand(Float64, UInt(4), 10) will work, but rand(Float64, (UInt(4), 10)) won’t, you’ll need rand(Float64, (4, 10)).
Thanks a lot for the answer! In my opinion this is super confusing and should just be leveled out, also, negative dims makes no real sense so using a UInt should be the preferred choice, no? Maybe there are other reasons for this?
This topic also extends far beyond Julia. Many languages opt for signed integer indices, and even the languages that use unsigned integer indices have a lot of nuance and caveats when you involve arithmetic. I’m linking the inventor of C++ Bjarne Stroustrup and the ISO C++ standards committee convener Herb Sutter suggesting signed integer types, warning of mixing integer types, and griping about such a mix stuck in the standard library. As for your question in particular:
Stroustrup: …Now, when people use unsigned numbers, they usually have a reason. And the reason will be something like, “well it can’t be negative”, or “I need an extra bit”. If you need an extra bit, I am very reluctant to believe you that you really need it, and I don’t think that’s a good reason. When you think you can’t have negative numbers, you will have somebody who initialize your unsigned with −2, and think they get −2, and things like that. It is just highly error-prone…
Sutter: …If you are writing a very large data structure, the only case where you would really care about the unsigned is if you know it’s an array of characters that’s going to be bigger than half of memory. I don’t know of any other case where it matters…
Array elements are often larger than 1 byte, which needs many times fewer integer indices than memory addresses, even for such an array completely filling addressable memory. 64-bit systems were mainstreamed before RAM exceeded the 4GiB limit of 32-bit systems, and we’ll likely move away from 64-bit systems before we ever have 16EiB RAM. We can afford to “waste” half of an integer range on indexing because arrays are just so rarely ≤1 byte per element AND large enough.