Strange behavior of iota

jmh530 john.michael.hall at
Wed Feb 16 19:35:00 UTC 2022

On Wednesday, 16 February 2022 at 15:55:55 UTC, bachmeier wrote:
> On Wednesday, 16 February 2022 at 15:21:11 UTC, jmh530 wrote:
>> On Tuesday, 15 February 2022 at 22:24:53 UTC, bachmeier wrote:
>>> [snip]
>>> After looking at the documentation and seeing 
>>> CommonType!(int, uint) is uint, I have to say that iota's 
>>> behavior doesn't make much sense.
>> What do you propose as an alternative? What about the 
>> narrowest type that fits both int and uint? That would be a 
>> long.
> My preference (in order)
> 1. Change everything to long. That way it works as anyone other 
> than the author of std.range.iota would expect.
> 2. Throw an error when casting from signed to unsigned. That 
> would at least prevent wrong output. The current behavior 
> delivers incorrect output 100% of the time, excluding the 
> trivial case where the correct output has zero elements.
> 3. Require the step to be positive.
> 4. Remove iota from Phobos because it silently changes correct 
> code to incorrect code that compiles and runs.

I've got an idea for combining 1 and 2.

Step 1: In the integral overloads, use allSatisfy!(isSigned, B, 
E) || allSatisfy!(isUnsigned, T, U) for the current behavior
Step 2: When !(allSatisfy!(isSigned, B, E) || 
allSatisfy!(isUnsigned, T, U)), then convert to narrowest common 
type as I mentioned (long in your case).

This would preserve the current size when the types are both 
either signed or unsigned and then would expand it only when 
there are different signed-ness. This also makes the behavior 
change at compile-time instead of throwing at runtime.

More information about the Digitalmars-d-learn mailing list