New Issue: Should ranges/domains be able to be counted using any integral type?

20085, "bradcray", "Should ranges/domains be able to be counted using any integral type?", "2022-06-27T18:23:47Z"

Today, when applying # to a range of integers, the count argument is expected to be an int or uint of matching width (or something that can coerce to that width). This can be particularly annoying when using a range of small ints but applying a count of default int type, e.g.:

config const n = 10;
var i8: int(8) = ...;
var r = 0..i8;  // r describes int(8) values
...r # n...   // Doesn't work today since `n` is int(64) which won't coerce to int(8) or uint(8)

In this issue, I'm proposing that # really shouldn't care about the integral type being passed in, only its value. I.e., if n was set to 1000 above, that should be a problem because it's too large, but the fact that n can take on larger values (but doesn't when it's 10) shouldn't be one.

I think the main historical argument for this was that if we think of # as being a binary operator then, like +, we'd define its arguments for similar types, where (a) we treated the range's idxType as the lhs type and (b) we extended the rhs to support signed and unsigned for convenience. But even ignoring those asymmetries, I don't think this rationale really holds up since (a) we don't have param ranges, which would be necessary to make them similarly flexible as + is today, and (b) # isn't a particularly symmetrical operation. Where it may make sense for + to end up generating the "greater" type of its two arguments (when one exists), for range op integral cases, I think it makes the most sense for the range's type to dominate, particularly given the prevalence of default integers in Chapel code (so their likelihood to be applied via a # operator. As a specific example, I don't think it makes sense to convert a range(int(8)) into a range(int(64)) just because an int(64) count is applied to it.

To me, this seems like a no-brainer, but I'm opening this for discussion to make sure others agree before proceeding.

This issue was forked off from a conversation starting here: iteration over a literal `int(64)..#uint(32)` range yields int(32)s · Issue #19958 · chapel-lang/chapel · GitHub