DMD 0.170 release

Bill Baxter wbaxter at gmail.com
Wed Oct 18 06:04:58 PDT 2006


Ary Manzana wrote:
> Walter Bright wrote:
> 
>> Bill Baxter wrote:
>>
>>> I don't see how it helps.  If you can already do:
>>>    foreach(T item; &collection.reversed()) { }
>>
>>
>> That doesn't work for arrays.
> 
> 
> Is "foreach_reverse" just there for arrays? To me it dosen't bother to 
> have a new keyword, but if it just exists to do:
> 
> for(int i = array.length - ; i >= 0; i--) {
>     // ...
> }
> 
> then it is realy superflous.
> 
> "foreach_reversed" just is useful for two things: arrays and lists. For 
> arrays you can always type the code above. For lists, give them a 
> "reversed" method that accepts a delegate, as I wrote. For other types 
> the "foreach" dosen't guarantee the order! (map, tree, set, etc.)
> 
> So "for(;;)" appears 5% of the time, convert it to "forever". :-)
> 
> I repeat: is "foreach_reverse" just there for arrays?


No, it at least works for arrays and any class with an "opApplyReverse" 
method, and for any delegate you feel like passing in.

Thus you can even do something nonsensical like:

    foreach_reverse(int i; &aggregate.opApply()) { }

And use foreach_reverse to iterate forwards over aggregate.  The only 
thing foreach_reverse gets you is the ability to magically call the 
magic method "opApplyReverse" on an object that has it.  Otherwise 
foreach_reverse is pretty much identical to foreach.  Oh, and I guess 
you get the ability to iterate backwards over the built-in types, too, 
which don't actually have opApply/opApplyReverse methods, but I think 
their lack of those methods is a missed opportunity.  If they just had 
opApply (or acted like they did) then there wouldn't be any need to make 
special case rules for them in the language.

So basically, without foreach_reverse you can set it up so you can do 
reverse iteration with something like:
     foreach(int i; &aggregate.reversed())
or
     foreach(int i; reversed(aggregate))

With it, you get to say
     foreach_reverse(int i; aggregate)
which actually is equivalent to
     foreach_reverse(int i; &aggregate.opApplyReverse())
which is also equivalent to
     foreach(int i; &aggregate.opApplyReverse())

Basically foreach_reverse is 99% identical to foreach, but whereas 
foreach has a secret pact with all classes to call their opApply method, 
foreach_reverse has a secret pact to call opApplyReverse.  In all other 
respects they are identical.  Really either one can be made to iterate 
any direction and any way you wish.  foreach can iterate backwards if 
you want, and foreach_reverse can iterate forwards.

It is pretty much the antithesis of orthogonality to have multiple, very 
similar constructs offeing very nearly identical functionality.  And 
meanwhile poor old 'static' is made to do the jobs of twenty big men 
because we can't afford another keyword to lighten his workload.  Yet 
foreach_reverse gets a seat at the big boys' table just for knowing how 
to call opApplyReverse()?

Doesn't seem reasonable to me.

But it could be worse.  At least foreach_reverse doesn't steal your 
socks or eat babies.  He is pretty easy to ignore if you don't like him.

--bb



More information about the Digitalmars-d-announce mailing list