Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
May 05, 2006 Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
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 |
May 07, 2006 Re: Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | 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. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
May 14, 2006 Re: Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | 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
|
May 15, 2006 Re: Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | 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... 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. -- Regards, James Dunne |
May 15, 2006 Re: Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
Posted in reply to James Dunne | 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 |
May 15, 2006 Re: Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | Chris Nicholson-Sauls skrev: > 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. You get it almost as sweet and simple by using a a wrapper struct. See for instance Andrew Fedoniouk's tree implementation: http://www.digitalmars.com/d/archives/digitalmars/D/dtl/378.html That allows: foreach(Node n; parent.forward) // all children from first to last foreach(Node n; parent.backward) // all children from last to first foreach(Node n; parent.deep) // all descendants - children and their /Oskar |
May 15, 2006 Re: Proposal: delegates as aggregates in foreach statements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | Chris Nicholson-Sauls wrote: > 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. :) > Seems to have worked then... >> 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. >> > > [snip] 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 And how! -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M--@ V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James Dunne |
Copyright © 1999-2021 by the D Language Foundation