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