Proposal: delegates as aggregates in foreach statements

Chris Nicholson-Sauls ibisbasenji at gmail.com
Mon May 15 00:08:28 PDT 2006


James Dunne wrote:
> Chris Nicholson-Sauls wrote:
> 
>> Bruno Medeiros wrote:
>>
>>> Chris Nicholson-Sauls wrote:
>>>
>>>> An idea occurred to me last night, which I'm sure must have come up 
>>>> before.  If it hasn't, I'm shocked, but I'm bringing it up (again?) 
>>>> anyway.  Why not allow a delegate (or even function pointer?) to be 
>>>> used as the "aggregate" parameter to a foreach statement, requiring 
>>>> that it expose the same signature as a valid opApply method?  For 
>>>> example:
>>>>
>>>> # class Foo {
>>>> #   private int[] p_data;
>>>> #
>>>> #   int opApply (int delegate(inout size_t, inout int) dg) {
>>>> #     int result = 0;
>>>> #     foreach (inout i, inout x; p_data) {
>>>> #       result = dg(i, x);
>>>> #       if (result)
>>>> #         break;
>>>> #     }
>>>> #     return result;
>>>> #   }
>>>> #
>>>> #   int reverse (int delegate(inout size_t, inout int) dg) {
>>>> #     int result = 0;
>>>> #     foreach (inout i, inout x; p_data.reverse) {
>>>> #       result = dg(i, x);
>>>> #       if (result)
>>>> #         break;
>>>> #     }
>>>> #     return result;
>>>> #   }
>>>> # }
>>>> #
>>>> # Foo foo = new Foo;
>>>> # foreach (size_t i, int x; &foo.reverse)
>>>> #   // ... do stuff ...
>>>>
>>>> One could even get real cute and use anonymous delegates:
>>>>
>>>> # foreach (size_t i, inout char[] x;
>>>> #   delegate int(int delegate (inout size_t ii, inout char[] xx) {
>>>> #     // implement iterator logic
>>>> #   }
>>>> # ) {
>>>> #   // ... do stuff ...
>>>> # }
>>>>
>>>> This, I think, would stand in the place of many uses of iterator 
>>>> objects and mutators.
>>>>
>>>> -- Chris Nicholson-Sauls
>>>
>>>
>>>
>>>
>>> Hum, seems like a sound proposal. I think it could be good.
>>>
>>>
>>
>> Well at least you thought so.  Doesn't look like it caught anyone 
>> else's eye.
>>
>> -- Chris Nicholson-Sauls
> 
> 
> Just because nobody replies doesn't mean nobody reads.  There's a lot of 
> content to plow through during the weekdays on this newsgroup.  I find 
> myself guilty of "Mark Thread As Read" (Thunderbird) a lot recently for 
> the threads I'm not interested in...

True enough.  I didn't really mean anything scathing by it, anyhow.  Honestly, it was a 
bump message.  :)

> Anyway, about your proposal...
> 
> I don't much see much utility in *anonymous* delegates for iteration 
> (lots of code duplication for commonly-iterated objects; and what's the 
> point of including complex iterator code next to the body of the 
> iteration itself?).
> 
> But, being able to select an iterator method for a class without 
> breaking that method into its own iterator object does have its uses. 
> For instance, reverse iteration and tree-walkers (pre-order, in-order, 
> post-order, etc.) look to be good candidates here.
> 

I think what I had in mind (and just didn't "vocalize") in using anonymous delegates, was 
to use them like wrappers around a list of other delegate calls or the like (multi-phase 
looping, perhaps).  I do see your point that in most cases if you were going to do that, 
you may as well just write the logic into the iteration block itself.  The tree-walkers 
and suchlike that you mention, though -- that's exactly the sort of thing I'm after. 
Being able to just do (foreach (i, x; &tree.walkInOrder) {...}) with .walkInOrder() being 
a simple method would be, pardon the colloquialism, wicked sweet.

-- Chris Nicholson-Sauls



More information about the Digitalmars-d mailing list