Mixed int/BigInt foreach interval

bearophile bearophileHUGS at lycos.com
Mon Sep 26 13:01:30 PDT 2011


In my opinion it's important to make BigInts work in most places where normal ints work. I think it's even worth modifying D language a bit (if and where necessary) to allow this.

Time ago I've asked to use BigInt with iota too (no D changes needed here):
http://d.puremagic.com/issues/show_bug.cgi?id=6447
because currently this doesn't work (std.traits.isIntegral needs to change, and there changes needed in iota too, because it can't use the current std.traits.unsigned, because a BigInt has no ".min" field):


import std.bigint, std.range;
void main() {
    foreach (i; iota(BigInt(10))) {}
}


Recently I've seen another situation where foreach can't be used in generic code that works with ints. This useless reduced code shows the situation:


import std.stdio, std.bigint;
void foo(T)(T n) {
    //for (T i = 1; i < n; i++)
    foreach (i; 1 .. n) // line 4
        writeln(i);
}
void main() {
    foo(5);
    foo(BigInt(5));
}


The error given:
test.d(4): Error: incompatible types for ((2) + (n)): 'int' and 'BigInt'


This too doesn't work:

import std.stdio, std.bigint;
void foo(T)(T n) {
    foreach (T i; 1 .. n) // line 3
        writeln(i);
}
void main() {
    foo(BigInt(5));
}


The error:
test.d(3): Error: cannot implicitly convert expression (1) of type int to BigInt


And even this doesn't work:

import std.stdio, std.bigint;
void foo(T)(T n) {
    foreach (i; T(1) .. n) // line 3
        writeln(i);
}
void main() {
    foo(BigInt(5));
}


The error:

...\dmd2\src\phobos\std\traits.d(3312): Error: static assert  "Type BigInt does not have an Unsigned counterpart"


And the "int(10)" syntax is not supported in D (it is supported in Python).

The sum of int and BigInt is supported, this works:

import std.bigint;
void main() {
    auto x = 1 + BigInt(1);
}



And this too works:

import std.stdio, std.bigint;
void main() {
    foreach (i; BigInt(1) .. BigInt(5))
        writeln(i);
}


That foreach error message looks similar to this type unification error:

import std.bigint;
void main() {
    BigInt x = BigInt(1);
    auto y = true ? 1 : x;
}

test.d(4): Error: incompatible types for ((1) ? (x)): 'int' and 'BigInt'


So is this foreach problem worth fixing? Is it fixable? Is all this fit for Bugzilla?

Bye, and thank you,
bearophile


More information about the Digitalmars-d mailing list