February 18, 2014 Re: foreach/iota countdown | ||||
---|---|---|---|---|
| ||||
Posted in reply to simendsjo | 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 Re: foreach/iota countdown | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brian Schott | 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 Re: foreach/iota countdown | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergei Nosov | >> /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 Re: foreach/iota countdown | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergei Nosov | 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
|
Copyright © 1999-2021 by the D Language Foundation