Jump to page: 1 2
Thread overview
foreach/iota countdown
Feb 17, 2014
simendsjo
Feb 17, 2014
Timon Gehr
Feb 17, 2014
simendsjo
Feb 17, 2014
Timon Gehr
Feb 17, 2014
simendsjo
Feb 17, 2014
Timon Gehr
Feb 17, 2014
simendsjo
Feb 17, 2014
Timon Gehr
Feb 17, 2014
Mengu
Feb 18, 2014
Brian Schott
Feb 18, 2014
Sergei Nosov
Feb 18, 2014
Ivan Kazmenko
Feb 18, 2014
bearophile
February 17, 2014
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
February 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 expected

The parameters can be runtime values. Auto-magically using a negative step would hence be a bad idea.
February 17, 2014
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.
February 17, 2014
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.

February 17, 2014
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?
February 17, 2014
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.
February 17, 2014
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.
February 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 expected

Ruby and Groovy has this feature. I'd support this.
February 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++){ } }

February 18, 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.
« First   ‹ Prev
1 2