[design] proposed change to small int -> real/complex conversions

Hi Chapel Users —

I'm posting this message to let users know about a proposed language change and to see whether it gives anyone concern. If so, please let me know by responding to this post or by direct message.

In a series of discussions over the past several months (and maybe even years?), we've been debating the merits of changing the way small integer types in Chapel implicitly convert to reals. Specifically, today, small signed/unsigned integers such as int(32), uint(8), and the like, when offered a choice between two overloads:

proc foo(x: real(32)) { ... }
proc foo(x: real(64)) { ... }

will pick the 64-bit version to implicitly convert to and call, where I believe the historical rationale for this was "int to float conversions can be lossy, and real(64) is our default floating point precision, so we'll convert to that to be 'safe'."

Having lived with this for years, users have pointed out that when you're trying to work at a smaller, fixed-precision bit-width (like "I want to use 32-bits to represent everything"), this requires a lot of painstaking casting to achieve the desired effect. As a result, it's been proposed that integer values will implicitly convert to any floating point size that matches or exceeds their bit-width, where the smaller size will be preferred if multiple are available. As a result, passing int/uint values with widths of 8, 16, and 32 would prefer the 32-bit version above, though they'd also be able to call into the 64-bit version if it were the only one available (and equivalently for complex(64) and complex(128) overloads).

As a tangible example of this, the following code would print real(64) in Chapel 1.26.0 and earlier, but would print real(32) if we proceeded with this approach:

var i: int(32);
var r: real(32);
var p = i * r;
writeln(p.type: string);

Thanks!
-Brad

1 Like