February 18, 2014
On Monday, 17 February 2014 at 19:22:38 UTC, simendsjo wrote:
> Should the following two uses be a compile-time error?
>   foreach(i; 10 .. 0) // Never executes
>
>   foreach(i; iota(10, 0)) // .. neither does this
>
> I would like the second to either be a compile-time error or automagically use a negative step.
>
> So we need to use a negative step in iota() or use a for loop
>   foreach(i; iota(10, 0, -1)) // as expected

I just added this check to DScanner:

-------------
import std.stdio;

void main(string[] args)
{
	auto x = args[3 .. 2];
	foreach (i; 20 .. 10)
	{
	}
}
-------------
/home/alaran/tmp/test.d(5:16)[warn]: 3 is larger than 2. This slice is likely incorrect.
/home/alaran/tmp/test.d(6:22)[warn]: 20 is larger than 10. Did you mean to use 'foreach_reverse( ... ; 10 .. 20)'?
February 18, 2014
On Tuesday, 18 February 2014 at 05:21:24 UTC, Brian Schott wrote:
> On Monday, 17 February 2014 at 19:22:38 UTC, simendsjo wrote:
>> Should the following two uses be a compile-time error?
>>  foreach(i; 10 .. 0) // Never executes
>>
>>  foreach(i; iota(10, 0)) // .. neither does this
>>
>> I would like the second to either be a compile-time error or automagically use a negative step.
>>
>> So we need to use a negative step in iota() or use a for loop
>>  foreach(i; iota(10, 0, -1)) // as expected
>
> I just added this check to DScanner:
>
> -------------
> import std.stdio;
>
> void main(string[] args)
> {
> 	auto x = args[3 .. 2];
> 	foreach (i; 20 .. 10)
> 	{
> 	}
> }
> -------------
> /home/alaran/tmp/test.d(5:16)[warn]: 3 is larger than 2. This slice is likely incorrect.
> /home/alaran/tmp/test.d(6:22)[warn]: 20 is larger than 10. Did you mean to use 'foreach_reverse( ... ; 10 .. 20)'?

Isn't foreach_reverse being deprecated?
February 18, 2014
>> /home/alaran/tmp/test.d(5:16)[warn]: 3 is larger than 2. This slice is likely incorrect.
>> /home/alaran/tmp/test.d(6:22)[warn]: 20 is larger than 10. Did you mean to use 'foreach_reverse( ... ; 10 .. 20)'?
>
> Isn't foreach_reverse being deprecated?

Oh.  If so, what would be the right way to iterate backwards?  The usual "for (*;*;*)" is too repetitive and error-prone: nothing is going to catch some "for (int i = 19; i >= 10; j--)" errors or the like.  Using ranges, such as iota and retro, currently results in a *massive* slowdown for DMD.

As a crude proof for the last statement, below are my local timings for DMD 2.064.2 on Win32 using "dmd -O -release -inline -noboundscheck" to compile.

Example 1 (0.38 sec):
void main () {foreach (i; 0..1_000_000_000) {}}

Example 2 (0.39 sec):
void main () {for (int i = 0; i < 1_000_000_000; i++) {}}

Example 3 (2.03 sec):
import std.range;
void main () {foreach (i; iota (1_000_000_000)) {}}

Unless simple things like example 3 run on par with the first two, foreach on ranges - or, in that regard, UFCS functional-style range chains without even a foreach - are just plain unacceptable in bottlenecks.  LDC is able to handle simple cases like this, but introducing a compiler dependency just because of this?  That would also be unfortunate.

Ivan Kazmenko.
February 18, 2014
Sergei Nosov:

> Isn't foreach_reverse being deprecated?

The idea was discussed a little, but it's not deprecated, and probably it will not be deprecated.

Bye,
bearophile
1 2
Next ›   Last »