October 17, 2006
Vladimir Kulev wrote:
> J Duncan wrote:
>> Disagree with you, its a nice thing to have.
> 
> There are many things which are nice to have, but only really essential ones
> should be in language itself. Reverse foreach can be implemented in other
> way.

But there are some benefits to having foreach_reverse, this I could think of right now:
- foreach and foreach_reverse are the basic kinds of iteration, supporting them both with a keyword and other kinds with a delegate makes sense as it looks more consistent imho.
- having foreach_reverse means that reverse iteration will likely be done with the same syntax across code from different people.
- it stands out more in code (syntax highlighting), I think this will be easier to read.

Sure it is syntactic sugar, but the D language does have a lot of sugar (more than most languages probably) and it can be pretty sweet.

I'm not saying it's better to have foreach_reverse perse, but it does have some benefits.





October 17, 2006
Bruno Medeiros wrote:
> Walter Bright wrote:
>> Added foreach_reverse, which addresses a serious shortcoming.
>>
>> http://www.digitalmars.com/d/changelog.html
> 
> foreach_reverse addresses a serious shortcoming? What is that, if instead of:
>   foreach_reverse(Foo f; aggregate) { ...
> I can do:
>   foreach(Foo f; &aggregate.opApplyReverse) { ...
> 
> The latter form is both more general (allows any kind of iterators) and more simple/orthogonal (no extra special statements are needed).

The latter form works now.
October 17, 2006
Ivan Senji wrote:
> Hmm, does foreach(Foo f; &aggregate.opApplyReverse) work/can be made to work if aggregate is Foo[]?

It can be, but it comes off looking hackish.

> If not, then I think foreach_reverse is useful.

It's a spoonful of syntactic sugar.
October 17, 2006
Chris Miller wrote:
> 
> interface IFoo
> {
>    void foo();
> }
> 
> class Foo: IFoo
> {
>    final void foo() { }
> }
> 
> DMD 0.170 output:
>    test.d(6): class test.Foo interface function IFoo.foo isn't implemented
> 
> Is this really what should happen? I thought final could mean it's still virtual if it's an interface implementation function or overriding something from a base class, just that it cannot be overridden again.

It's a bug.
October 17, 2006
Walter Bright wrote:
> Hasan Aljudy wrote:
>> Also, since foreach already takes two arguments (int i, T t) that is, index and element, you can add a third argument, of bool type, with the meaning "start in reverse mode"
>> foreach( true, i, d; "Hello" )
>> {
>>     writefln( d );
>> }
>>
>> should print:
>> o
>> l
>> l
>> e
>> H
> 
> That would work, and something like it has been suggested before, but it is too obscure looking. When someone sees "foreach_reverse", I think it'll be very clear what's going on.

There's no need to use booleans (at least, not directly):

enum Ordering : bool { forward, backwards, reversed = backwards }

That should produce much more readable code, but work the same. Can be done right now, except you can't overload opApply for arrays :(. (Tell me if I'm wrong, but I tried and it didn't work)
October 17, 2006
Walter Bright wrote:
> Lars Ivar Igesund wrote:
>> But foreach_reverse is such an ugly name, then I like 'reveach' (courtesy of
>> Mr Panek) much better :P
> 
> The saving grace about foreach_reverse is:

[... three points I agree with ...]

> 4) It is analogous with C++'s reverse_iterator names.

Actually, wouldn't reverse_foreach be analogous with C++'s reverse_iterator naming? :P
October 17, 2006
Tom S wrote:

[snip proposal]

I'd definitely vote for this. It would be a new evolutionary step for D. The suggestion is an extremely powerful and generic construct that generalizes not only the foreach iterator constructs, but many others aswell. Just some quick thoughts:

You could reimplement the while-loop:

void _while(lazy bool condition, void delegate() dg, inout void* ret) {...}

The infinite loop could finally be expressed without cludges:

forever {...}

You could make your own threading construct:

asynchronously { s.connect(); s.send(something); s.close(); }

Or why not:

foreach_parallel (objects) (Object o) {
  o.doSomething();
}

A custom synchronization construct:

mySynchronized("namedLock") {
 ...
}

The possibilities seem endless. It is almost scary. And best of all: It doesn't contain a single template. :)

/Oskar
October 17, 2006
Tom S wrote:
> 

This is a great proposal and would make d stand out among similar languages.

Walter please implement this.
October 17, 2006
Frits van Bommel wrote:
> Walter Bright wrote:
>> 4) It is analogous with C++'s reverse_iterator names.
> 
> Actually, wouldn't reverse_foreach be analogous with C++'s reverse_iterator naming? :P

The problem with naming things "iterator" and "reverse_iterator" is they wind up widely separated when doing an alpha sort.
October 17, 2006
J Duncan wrote:
> Vladimir Kulev wrote:
> 
>> Agree with you, foreach_reverse is unnecessary feature, so it should not
>> exist.
> 
> Disagree with you, its a nice thing to have.

Could we make the statement that the old construct
	foreach(int i; a) {...}
is now considered to just be syntax sugar for:
	foreach(int i; a.opApply) {...}
and similarly for foreach_reverse?

If so, then really the question here is whether we think this syntax sugar is worth having.

Russ