## digitalmars.D.learn - for ranges

Russel Winder via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
```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=E2=80=A6

The standard explicit iteration form uses a loop:

for(i; 2..n+1)

for n =3D 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?

--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder ekiga.n=
et
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
```
Jan 22 2015
"bearophile" <bearophileHUGS lycos.com> writes:
```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
```
Jan 22 2015
"bearophile" <bearophileHUGS lycos.com> writes:
``` 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
```
Jan 22 2015
Russel Winder via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
```On Thu, 2015-01-22 at 16:48 +0000, bearophile via Digitalmars-d-learn
wrote:
It works for me:

=20
Sorry, you are right, it loops:

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

--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder ekiga.n=
et
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
```
Jan 22 2015
Steven Schveighoffer <schveiguy yahoo.com> writes:
```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
```
Jan 22 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.
```
Jan 23 2015
Steven Schveighoffer <schveiguy yahoo.com> writes:
```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
```
Jan 23 2015