Re: foreach/iota countdown
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
Re: foreach/iota countdown
/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.
Re: foreach/iota countdown
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?
Re: foreach/iota countdown
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)'?
Re: foreach/iota countdown
On Monday, 17 February 2014 at 20:21:30 UTC, simendsjo wrote: I wouldn't call it randomly. In that case you should call it randomly that it suddenly doesn't run once you try to step downward. I didn't had time to work more on the iota. Perhaps after 2.065 is out I can resume working on that, but I'm really short of time right now. Allowing iota to iterate downward might become a horrible idea when we finally extend iota to other non-numeric types. The big issue is that types that define both opUnary!"++" and opUnary!"--" would behave in a completely different way from types that only define opUnary!"++". from http://forum.dlang.org/thread/mwwznnobgecnwermr...@forum.dlang.org example: type T implements ++t and --t; type P only implements ++p; t1 < t2 => iota(t2, t1) has a way to compute a non-empty range; p1 < p2 => iota(p2, p1) can do nothing but return an empty range; This really looks like a minefield to me.
Re: foreach/iota countdown
On 02/17/2014 10:12 PM, simendsjo wrote: Ok, I yield. I just happened to write foreach(i; 10 .. 0) and was suprised that it didn't give any warnings or errors. But I still somewhat stand by my point: Dead code is illegal in D, (No it is not. Some forms of dead code are detected by DMD, but only with the -w switch.) and this is code that will never run, hence dead code. The following does not give any warnings or errors either: void main(){ for(int i=10;i<0;i++){ } }
Re: foreach/iota countdown
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 Ruby and Groovy has this feature. I'd support this.
Re: foreach/iota countdown
On Monday, 17 February 2014 at 21:06:50 UTC, Timon Gehr wrote: On 02/17/2014 09:21 PM, simendsjo wrote: On Monday, 17 February 2014 at 20:03:32 UTC, Timon Gehr wrote: ... It was just to illustrate the issue more clearly. Eg. it means one and the same iota expression can sometimes iterate in one direction and in the other direction at other times. That's simply not useful behaviour. I'm not sure what I find more confusing. Ok if it's a deliberate choice never to change the step direction, but is it deliberate that it's not an error to have a greater lower bound than upper bound? Or is this just the way it happened to be implemented? That's deliberate. I don't really understand how it is confusing. To draw an analogy, given (low ∈ ℕ) and (high ∈ ℕ), { x ∈ ℕ | low ≤ x ∧ x < high } is just the empty set if low > high. It is not illegal or unusual. Ok, I yield. I just happened to write foreach(i; 10 .. 0) and was suprised that it didn't give any warnings or errors. But I still somewhat stand by my point: Dead code is illegal in D, and this is code that will never run, hence dead code.
Re: foreach/iota countdown
On 02/17/2014 09:21 PM, simendsjo wrote: On Monday, 17 February 2014 at 20:03:32 UTC, Timon Gehr wrote: ... It was just to illustrate the issue more clearly. Eg. it means one and the same iota expression can sometimes iterate in one direction and in the other direction at other times. That's simply not useful behaviour. I'm not sure what I find more confusing. Ok if it's a deliberate choice never to change the step direction, but is it deliberate that it's not an error to have a greater lower bound than upper bound? Or is this just the way it happened to be implemented? That's deliberate. I don't really understand how it is confusing. To draw an analogy, given (low ∈ ℕ) and (high ∈ ℕ), { x ∈ ℕ | low ≤ x ∧ x < high } is just the empty set if low > high. It is not illegal or unusual.
Re: foreach/iota countdown
On Monday, 17 February 2014 at 20:03:32 UTC, Timon Gehr wrote: On 02/17/2014 08:33 PM, simendsjo wrote: On Monday, 17 February 2014 at 19:30:38 UTC, Timon Gehr wrote: On 02/17/2014 08:22 PM, 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 The parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea. Why would it be a bad idea? The step direction shouldn't randomly change. I wouldn't call it randomly. In that case you should call it randomly that it suddenly doesn't run once you try to step downward. And I don't see where the runtime aspect comes in. It was just to illustrate the issue more clearly. Eg. it means one and the same iota expression can sometimes iterate in one direction and in the other direction at other times. That's simply not useful behaviour. I'm not sure what I find more confusing. Ok if it's a deliberate choice never to change the step direction, but is it deliberate that it's not an error to have a greater lower bound than upper bound? Or is this just the way it happened to be implemented?
Re: foreach/iota countdown
On 02/17/2014 08:33 PM, simendsjo wrote: On Monday, 17 February 2014 at 19:30:38 UTC, Timon Gehr wrote: On 02/17/2014 08:22 PM, 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 The parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea. Why would it be a bad idea? The step direction shouldn't randomly change. And I don't see where the runtime aspect comes in. It was just to illustrate the issue more clearly. Eg. it means one and the same iota expression can sometimes iterate in one direction and in the other direction at other times. That's simply not useful behaviour. There would be a very small setup performance hit when using runtime variables for choosing the step direction.
foreach/iota countdown
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
Re: foreach/iota countdown
On Monday, 17 February 2014 at 19:30:38 UTC, Timon Gehr wrote: On 02/17/2014 08:22 PM, 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 The parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea. Why would it be a bad idea? And I don't see where the runtime aspect comes in. There would be a very small setup performance hit when using runtime variables for choosing the step direction.
Re: foreach/iota countdown
On 02/17/2014 08:22 PM, 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 The parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea.