Thread overview
for ranges
Jan 22, 2015
Russel Winder
Jan 22, 2015
bearophile
Jan 22, 2015
bearophile
Jan 22, 2015
Russel Winder
Jan 23, 2015
ixid
January 22, 2015
Playing with factorial implementations, as you do. I had a D implementation using ulong. Not sensible obviously since overflow is a bit of a problem. But the code worked, as did the tests. Now converting to BigInt and…

The standard explicit iteration form uses a loop:

	for(i; 2..n+1)

for n = 0 or 1 this loop doesn't loop since the range is [,). However for BigInt:

	for(i; two..n + one)

the loop starts at 0 and just keeps on going. This is clearly not good.

Am I having a mental breakdown or is this a real bug?


-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


January 22, 2015
Russel Winder:

> However for BigInt:
>
> 	for(i; two..n + one)
>
> the loop starts at 0 and just keeps on going. This is clearly not good.

It works for me:

void main() {
    import std.stdio, std.bigint;

    immutable BigInt one = 1;
    immutable BigInt two = 2;
    uint n = 100;

    foreach (immutable i; two .. n + one)
        i.writeln;
}


Bye,
bearophile
January 22, 2015
> It works for me:

Sorry, you are right, it loops:

void main() {
    import std.stdio, std.bigint;

    immutable BigInt one = 1;
    immutable BigInt two = 2;
    uint n = 0;

    foreach (immutable i; two .. n + one)
        i.writeln;
}


Bye,
bearophile
January 22, 2015
On Thu, 2015-01-22 at 16:48 +0000, bearophile via Digitalmars-d-learn wrote:
> > It works for me:
> 
> Sorry, you are right, it loops:

So it is a bug, and I now have to find out how to report it!

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


January 22, 2015
On 1/22/15 11:41 AM, Russel Winder via Digitalmars-d-learn wrote:
> Playing with factorial implementations, as you do. I had a D
> implementation using ulong. Not sensible obviously since overflow is a
> bit of a problem. But the code worked, as did the tests. Now converting
> to BigInt and…
>
> The standard explicit iteration form uses a loop:
>
> 	for(i; 2..n+1)
>
> for n = 0 or 1 this loop doesn't loop since the range is [,). However
> for BigInt:
>
> 	for(i; two..n + one)
>
> the loop starts at 0 and just keeps on going. This is clearly not good.
>
> Am I having a mental breakdown or is this a real bug?
>
>

The issue:

import std.stdio;

struct S
{
    int x;
    int opCmp(const S other) const { writeln("compare"); return x < other.x ? -1 : x > other.x ? 1 : 0;}
    bool opEquals(const S other) const { writeln("equals"); return x == other.x;}
    ref S opOpAssign(string op)(int other)
    {
        mixin("x " ~ op ~ "= other;");
        return this;
    }
}

void main()
{
    immutable S one = S(1);
    immutable S two = S(2);
    foreach(s; one..two) {}
}

output:
equals
equals

So foreach(S; one..two) translates to:

for(S x = one; x != two; x += 1)

which explains the infinite loop. I'm almost positive foreach(x; 1..2) uses comparison instead of equality to check for end condition.

-Steve
January 23, 2015
On Thursday, 22 January 2015 at 16:41:49 UTC, Russel Winder wrote:
> Playing with factorial implementations, as you do. I had a D
> implementation using ulong. Not sensible obviously since overflow is a
> bit of a problem. But the code worked, as did the tests. Now converting
> to BigInt and…
>
> The standard explicit iteration form uses a loop:
>
> 	for(i; 2..n+1)
>
> for n = 0 or 1 this loop doesn't loop since the range is [,). However
> for BigInt:
>
> 	for(i; two..n + one)
>
> the loop starts at 0 and just keeps on going. This is clearly not good.
>
> Am I having a mental breakdown or is this a real bug?

In general it feels as if BigInt needs more work as it doesn't
work with simple generic code in too many cases. Templates get
confused by invocation with a literal and a BigInt for example
when it should have a single type. Literals feel too strongly
typed or too weakly implicitly convertible.
January 23, 2015
On 1/23/15 4:44 AM, ixid wrote:
> On Thursday, 22 January 2015 at 16:41:49 UTC, Russel Winder wrote:
>> Playing with factorial implementations, as you do. I had a D
>> implementation using ulong. Not sensible obviously since overflow is a
>> bit of a problem. But the code worked, as did the tests. Now converting
>> to BigInt and…
>>
>> The standard explicit iteration form uses a loop:
>>
>>     for(i; 2..n+1)
>>
>> for n = 0 or 1 this loop doesn't loop since the range is [,). However
>> for BigInt:
>>
>>     for(i; two..n + one)
>>
>> the loop starts at 0 and just keeps on going. This is clearly not good.
>>
>> Am I having a mental breakdown or is this a real bug?
>
> In general it feels as if BigInt needs more work as it doesn't
> work with simple generic code in too many cases. Templates get
> confused by invocation with a literal and a BigInt for example
> when it should have a single type. Literals feel too strongly
> typed or too weakly implicitly convertible.

This is not a BigInt problem, it's an inconsistency with foreach range. See my earlier post.

-Steve