Re: foreach/iota countdown

2014-02-18 Thread bearophile

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

2014-02-18 Thread 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?


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

2014-02-18 Thread Sergei Nosov

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

2014-02-17 Thread Brian Schott

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

2014-02-17 Thread Francesco Cattoglio

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

2014-02-17 Thread Timon Gehr

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

2014-02-17 Thread Mengu

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

2014-02-17 Thread simendsjo

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

2014-02-17 Thread Timon Gehr

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

2014-02-17 Thread simendsjo

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

2014-02-17 Thread Timon Gehr

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

2014-02-17 Thread simendsjo

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

2014-02-17 Thread simendsjo

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

2014-02-17 Thread Timon Gehr

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.