May 18, 2009
Leandro Lucarella:

> > foreach(i, elem; retro(someArray)) {}
> 
> Python has an "enumerate" function exactly for this.

Not exactly for that. To have something like that you need something more (reversed is lazy):

>>> iterable = "abcd"
>>> for i, elem in enumerate(reversed(iterable)):
...     print i, elem
...
0 d
1 c
2 b
3 a

Bye,
bearophile
May 18, 2009
Denis Koroskin wrote:
> On Mon, 18 May 2009 04:28:24 +0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> Consider:
>>
>>      foreach (x; 1.0 .. 4.1) writeln(x);
>>      foreach_reverse (x; 1.0 .. 4.1) writeln(x);
>>
>> This sucks. foreach with interval for floating-point types should be disallowed.
>>
>>
>> Andrei
> 
> It's useless, unless a step is specified (btw, integer iteration would benefit from having a step, too)
> 
> I don't mind if the whole .. feature is removed. It could be implemented in a library, with an optional step:
> 
> foreach (x; range(0, 100)) { // step is 1 implicitly
>    // ...
> }
> 
> foreach (x; range(0, 100, 2)) { // explicit step
>    // ...
> }
> 
> This feels more functional, although slightly longer to type.
> 

It's actually there already: std.range.iota. Incidentally it does the right thing with floats because it iterates by the recurrence formula iter(i) = lowest + i * step (where i is an integer). But there's an unrelated bugzilla about it.


Andrei
May 18, 2009
Steven Schveighoffer wrote:
> On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> Consider:
>>
>>      foreach (x; 1.0 .. 4.1) writeln(x);
>>      foreach_reverse (x; 1.0 .. 4.1) writeln(x);
>>
>> This sucks. foreach with interval for floating-point types should be disallowed.
> 
> foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better.
> 
> foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable).

I'm a bit leery about this - what if user code has a bug and I transform that into a feature?

> foreach(x; array.reverse) should iterate in reverse.

foreach (x; array.retro) already works.

> for classes, using a method called reverse should work fine:
> 
> foreach(x; myclass.reverse)
> 
> Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous.  Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that?

I agree.


Andrei
May 18, 2009
Steven Schveighoffer wrote:
> On Mon, 18 May 2009 09:54:16 -0400, Jacob Carlborg <doob@me.com> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>
>>>> Consider:
>>>>
>>>>      foreach (x; 1.0 .. 4.1) writeln(x);
>>>>      foreach_reverse (x; 1.0 .. 4.1) writeln(x);
>>>>
>>>> This sucks. foreach with interval for floating-point types should be disallowed.
>>>  foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better.
>>>  foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable).
>>> foreach(x; array.reverse) should iterate in reverse.
>>>  for classes, using a method called reverse should work fine:
>>>  foreach(x; myclass.reverse)
>>>  Having to implement opApplyReverse is rediculous, and having a keyword like foreach_reverse is rediculous.  Reverse isn't the only interesting iteration pattern, so why focus a whole keyword and syntax on that?
>>>  -Steve
>>
>> I agree with that, but how would you differ foreach(x; array.reverse) from the array.reverse that modifies the array?
> 
> D'oh! I picked the wrong property name.  Forgot about the existing reverse property!
> 
> Just to clarify, I am *not* advocating that the propery way to iterate an array in reverse is to first reverse the array!
> 
> So pick some other property name:
> 
> foreach(x; array.backwards)
> 
> or whatever.  Too bad reverse is already taken :(
> 
> -Steve

sort and reverse for slices should go, by the way.

Andrei
May 18, 2009
dsimcha wrote:
> 2.  Using retro() would not be a full replacement when it comes to arrays.  For
> example, you can't get the indices by doing a
> 
> foreach(i, elem; retro(someArray)) {}

This needs fixing.

> 4.  Iteration using the range interface is currently slower than with arrays.  I
> posted some benchmarks a while back that were meant to demonstrate something else
> but demonstrated this as a side effect.  This is unlikely to matter unless you're
> in a very small inner loop, such that the loop overhead is significant compared to
> the contents of the loop, but some people with insane performance requirements
> might care.

Yah, popFront changes two words instead of one.


Andrei
May 18, 2009
On Mon, 18 May 2009 12:02:30 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Steven Schveighoffer wrote:
>> On Sun, 17 May 2009 20:28:24 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> Consider:
>>>
>>>      foreach (x; 1.0 .. 4.1) writeln(x);
>>>      foreach_reverse (x; 1.0 .. 4.1) writeln(x);
>>>
>>> This sucks. foreach with interval for floating-point types should be disallowed.
>>  foreach_reverse sucks in its own right, while you're looking for stuff to get rid of, I think it can be done better.
>>  foreach(x; 4 .. 1 ) should do a reverse interval (and looks way more readable).
>
> I'm a bit leery about this - what if user code has a bug and I transform that into a feature?

hm... I guess that's one way to look at it.  I don't anticipate many typing this by mistake.  One thing that would be left to decide, 1..4 means 1-2-3, should 4..1 mean 4-3-2 or 3-2-1?  I'd vote for 4-3-2 to be consistent on having x..y mean inclusive to exclusive.

>
>> foreach(x; array.reverse) should iterate in reverse.
>
> foreach (x; array.retro) already works.

As I said later, I'm not stuck on the name.  Just that it should be a property (BTW, has the requirement for parens after an array "property" been fixed yet?).

I don't care if it's a library solution as long as the library solution can perform as well as the current solution, and can implement the api of the current solution (i.e. can also iterate indexes).  Otherwise, you'll have grumbling ;)

-Steve
May 18, 2009
Steven Schveighoffer:

> hm... I guess that's one way to look at it.  I don't anticipate many typing this by mistake.  One thing that would be left to decide, 1..4 means 1-2-3, should 4..1 mean 4-3-2 or 3-2-1?  I'd vote for 4-3-2 to be consistent on having x..y mean inclusive to exclusive.

Python shows the coherent behavior:

>>> list(xrange(4, 1))
[]
>>> list(xrange(4, 1, -1))
[4, 3, 2]

It's easy to convince me that other behaviors are more correct.

Bye,
bearophile
May 18, 2009
On Mon, May 18, 2009 at 9:21 AM, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> On Mon, 18 May 2009 12:02:30 -0400, Andrei Alexandrescu
>> I'm a bit leery about this - what if user code has a bug and I transform that into a feature?
>
> hm... I guess that's one way to look at it.  I don't anticipate many typing this by mistake.

Can't you use variables in those ".." expressions?   If so it's not so obvious when you see x..y that y is less than x.

--bb
May 18, 2009
On Mon, 18 May 2009 13:30:19 -0400, Bill Baxter <wbaxter@gmail.com> wrote:

> On Mon, May 18, 2009 at 9:21 AM, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>> On Mon, 18 May 2009 12:02:30 -0400, Andrei Alexandrescu
>>> I'm a bit leery about this - what if user code has a bug and I transform
>>> that into a feature?
>>
>> hm... I guess that's one way to look at it.  I don't anticipate many typing
>> this by mistake.
>
> Can't you use variables in those ".." expressions?   If so it's not so
> obvious when you see x..y that y is less than x.

And what happens today if y is less than x?  Just no loop iterations, or does it wrap?

Honestly, I thought it was a compile time feature only.

Can you use delegates/properties also?

In that case, returning a range that's reversed is the only alternative...  It's still better than foreach_reverse(x; 1..4) IMO.

-Steve
May 18, 2009
bearophile, el 18 de mayo a las 11:19 me escribiste:
> Leandro Lucarella:
> 
> > > foreach(i, elem; retro(someArray)) {}
> > 
> > Python has an "enumerate" function exactly for this.
> 
> Not exactly for that. To have something like that you need something more (reversed is lazy):
> 
> >>> iterable = "abcd"
> >>> for i, elem in enumerate(reversed(iterable)):
> ...     print i, elem
> ...
> 0 d
> 1 c
> 2 b
> 3 a

That's exactly what I was saying, you removed the context of my message.

In D2 that would be:
foreach (i, elem; enumerate(retro(someArray))) {}

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
1 2 3
Next ›   Last »