digitalmars.D.learn - foreach/iota countdown
- simendsjo (7/7) Feb 17 2014 Should the following two uses be a compile-time error?
- Timon Gehr (3/10) Feb 17 2014 The parameters can be runtime values. Auto-magically using a negative
- simendsjo (5/18) Feb 17 2014 Why would it be a bad idea? And I don't see where the runtime
- Timon Gehr (5/24) Feb 17 2014 It was just to illustrate the issue more clearly. Eg. it means one and
- simendsjo (8/33) Feb 17 2014 I wouldn't call it randomly. In that case you should call it
- Timon Gehr (5/15) Feb 17 2014 That's deliberate. I don't really understand how it is confusing.
- simendsjo (6/30) Feb 17 2014 Ok, I yield. I just happened to write
- Timon Gehr (5/10) Feb 17 2014 (No it is not. Some forms of dead code are detected by DMD, but only
- Francesco Cattoglio (17/20) Feb 17 2014 I didn't had time to work more on the iota. Perhaps after 2.065
- Mengu (2/9) Feb 17 2014 Ruby and Groovy has this feature. I'd support this.
- Brian Schott (16/23) Feb 17 2014 I just added this check to DScanner:
- Sergei Nosov (2/28) Feb 18 2014 Isn't foreach_reverse being deprecated?
- Ivan Kazmenko (22/27) Feb 18 2014 Oh. If so, what would be the right way to iterate backwards?
- bearophile (5/6) Feb 18 2014 The idea was discussed a little, but it's not deprecated, and
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
Feb 17 2014
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 expectedThe parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea.
Feb 17 2014
On Monday, 17 February 2014 at 19:30:38 UTC, Timon Gehr wrote:On 02/17/2014 08:22 PM, simendsjo wrote: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.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 expectedThe parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea.
Feb 17 2014
On 02/17/2014 08:33 PM, simendsjo wrote:On Monday, 17 February 2014 at 19:30:38 UTC, Timon Gehr wrote:The step direction shouldn't randomly change.On 02/17/2014 08:22 PM, simendsjo wrote:Why would it be a bad idea?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 expectedThe parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea.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.
Feb 17 2014
On Monday, 17 February 2014 at 20:03:32 UTC, Timon Gehr wrote:On 02/17/2014 08:33 PM, 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.On Monday, 17 February 2014 at 19:30:38 UTC, Timon Gehr wrote:The step direction shouldn't randomly change.On 02/17/2014 08:22 PM, simendsjo wrote:Why would it be a bad idea?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 expectedThe parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea.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?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.
Feb 17 2014
On 02/17/2014 09:21 PM, simendsjo wrote:On Monday, 17 February 2014 at 20:03:32 UTC, Timon Gehr wrote: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.... 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?
Feb 17 2014
On Monday, 17 February 2014 at 21:06:50 UTC, Timon Gehr wrote:On 02/17/2014 09:21 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, and this is code that will never run, hence dead code.On Monday, 17 February 2014 at 20:03:32 UTC, Timon Gehr wrote: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.... 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?
Feb 17 2014
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++){ } }
Feb 17 2014
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/mwwznnobgecnwermrndq 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.
Feb 17 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 expectedRuby and Groovy has this feature. I'd support this.
Feb 17 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 expectedI 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)'?
Feb 17 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:Isn't foreach_reverse being deprecated?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 expectedI 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)'?
Feb 18 2014
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./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?
Feb 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
Feb 18 2014