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. 

Well....  We are lucky to have Walter then.... :)
October 17, 2006
> Although could someone explain what exactly "null is now an exact match for null pointers, delegates, arrays, class objects, etc." changed?

I also want to know this.
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).
> 

Hmm, does foreach(Foo f; &aggregate.opApplyReverse) work/can be made to work if aggregate is Foo[]?

If not, then I think foreach_reverse is useful.
October 17, 2006
Tom S wrote:

<snip>great proposal</snip>

Seems to me (after getting through the fog of cold) that Tom is on a rampage today. This would allow almost everything of looping one could think of, and that without templates and specialized constructs/opSomethings at all (although I'm sure Tom would abuse templates to make sure that some even more magnificent could come out of it).

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource & #D: larsivi
October 17, 2006
BCS wrote:
> Ary Manzana wrote:
> 
> 
> 
>  class Tree {
> 
>      int inorder(int delegate(inout int)) {
>              // inorder traversal
>      }
> 
>      int preorder(int delegate(inout int)) {
>              // preorder traversal
>      }
> 
>     int postorder(int delegate(inout int)) {
>              // postorder traversal
>      }
> 
>  }
> 
>  void main() {
>      Tree t = giveMeSomeTree();
> 
>      foreach(int i : &t.inorder) {
>          // something
>          }
> 
>      foreach(int i : &t.preorder) {
>          // something
>          }
> 
>      foreach(int i : &t.postorder) {
>          // something
>          }
> 
>  }
> 
> If I understand correctly, the above works with what is there now.

You are correct, with delegates now allowed as the 'aggregate', you can have any order traversal needed for the particular collection type. (Nit: replace the ':' in your examples with ';'.)

> The things with the foreach_reverse is (I think) mostly for actuals arrays, and the opApplyReverse is really there more for orthogonality than need. that orthogonality has some cool side effects* so I'd say leave them in.

Right. a.reverse reverses an array in place, and trying to support:
	int[] a;
	foreach (v; &a.reverse)
is an awful hack.
October 17, 2006
Ary Manzana wrote:
> Could something like this be done? I think it has the clearest syntax: no new keywords needed and very flexible. The compiler should check that the right side of the foreach is an array, or a class or struct having opApply, or a delegate of the singature I mentioned before.

Already done! See BCS's post.
October 17, 2006
Hasan Aljudy wrote:
> I just go an idea.
> How about adding new statements:
> skip;
> reverse;
> 
> They can be used inside the foreach body to skip over the next iteration

continue;

can be used for that.

> or reverse the order of iteration (dynamically at runtime).

Aaaaggghhhh!!!!

> 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.
October 17, 2006
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:

1) Only a small (5% ?) of loops will be reverse, so you won't see it or need to type it that often.

2) It's very clear what it does.

3) It isn't likely to conflict with other names.

4) It is analogous with C++'s reverse_iterator names.
October 17, 2006
Serg Kovrov wrote:
> Hi Walter Bright, you wrote:
>> Added foreach_reverse, which addresses a serious shortcoming.
>> http://www.digitalmars.com/d/changelog.html
> 
> Thanks for great work, Walter!
> 
> Although could someone explain what exactly "null is now an exact match for null pointers, delegates, arrays, class objects, etc." changed?

It makes overloading work more naturally. See bugzilla 412 for an example. It now works analogously to string literals, which will match any string type exactly.
October 17, 2006
Jarrett Billingsley wrote:
> "Lars Ivar Igesund" <larsivar@igesund.net> wrote in message news:eh2fl7$2n9g$1@digitaldaemon.com...
>> Walter, you always say that new features shouldn't be added if they fairly
>> easily can be done with existing language constructs. Now, the post below
>> is about possible new features in D (of general interest and with many
>> possible applications), and it is shown how they can be used to implement
>> an existing (and specific) feature in D. I'm not sure if this should be
>> used as an argument for removing the new delegate-as-aggregate feature, but
>> it certainly shows that the proposed features have merit.

I think Tom S's proposed new features have merit, but I have to disagree that they are better for looping than the new delegate approach.

> While I agree that foreach_reverse seems superfluous with the ability to pass in any delegate as the container, the delegate-as-container is just _too damn cool_ not to implement.  I don't know about you, but I'd rather use a single ampersand than go through all that mixin-in and aliasing just to get it to work.  That, and with the delegate-as-container, you're no longer limited to just class members - you could have just a nested function which you pass in.  Without delegate-as-container, you'd have to create a dummy class with the appropriate mixed-in opApply to get it to work. 

I agree with that. Note that:

	foreach (v; aggr)

is shorthand for:

	foreach (v; &aggr.opApply)

in other words, if you've figured out how to write opApply, you've figured out how to write any visitation order, by just changing the name of it. As an aside, I've always disliked designs that needed dummy classes <g>.