Custom Blocks

Robert Jacques sandford at jhu.edu
Fri Aug 13 20:34:31 PDT 2010


On Thu, 12 Aug 2010 14:56:54 -0400, KennyTM~ <kennytm at gmail.com> wrote:

> On Aug 12, 10 23:42, Robert Jacques wrote:
>> On Thu, 12 Aug 2010 07:43:25 -0400, KennyTM~ <kennytm at gmail.com> wrote:
>>
>>> On Aug 12, 10 10:25, Robert Jacques wrote:
>>>> On Wed, 11 Aug 2010 17:54:35 -0400, Tomek Sowiński <just at ask.me>  
>>>> wrote:
>>>>
>>>>> Robert Jacques napisał:
>>>>>
>>>>>>> I was thinking something like this:
>>>>>>>
>>>>>>> void fun(int x, int y, int z, delegate void(int, int, int) dg)
>>>>>>>
>>>>>>> fun(x, y, z, a, b, c) { body }
>>>>>>>
>>>>>>> |
>>>>>>> V
>>>>>>>
>>>>>>> fun(x, y, z, (a, b, c) { body });
>>>>>>
>>>>>> Mixing function args with delegate args makes me think of foreach:
>>>>>>
>>>>>> fun(x, y, z, (a, b, c) { body }); <=> fun(a, b, c; x, y, z) { body }
>>>>>
>>>>> All great, but if there's no remedy for the return WTF, I'd leave  
>>>>> this
>>>>> (nice) feature in the drawer.
>>>>>
>>>>> void foo() {
>>>>> fun(a, b, c; x, y, z) {
>>>>> return; // who returns?
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>> Tomek
>>>>
>>>> Fun does. This is the same as function/delegate literals today.
>>>> Of course, putting a return statement inside a foreach block is  
>>>> probably
>>>> a buggy edge case right now; sometimes it causes the parent scope to
>>>> return and sometimes it doesn't compile.
>>>
>>> This is an unacceptable buggy edge case. Consider the already-working
>>> code
>>>
>>> int find_three(int[] arr) {
>>> foreach (i, x; arr) {
>>> if (x == 3)
>>> return i;
>>> }
>>> return -1;
>>> }
>>>
>>> If I replace the foreach with a custom block e.g.
>>>
>>> int find_three_retro(int[] arr) {
>>> foreach_retro (i, x; arr) {
>>> if (x == 3)
>>> return i;
>>> }
>>> return -1;
>>> }
>>>
>>> then suddenly the function doesn't work anymore. It's better not to
>>> provide a feature inconsistent with other parts of the language.
>>
>> Code that exploits a bug in the implementation isn't "working" in any
>> sense of the word. One of the points I was making is that return
>> statements inside a foreach do different things depending on what you're
>> foreaching over. So this feature would be adding consistency, not
>> removing it.
>
>
>
> void locate_three_or_five(int[] arr) {
>     int res = -1;
>     foreach (i, x; arr) {
>        if_is_one_of(x, [3, 5]) {
>           res = i;
>           break;     // now what?
>        }
>     }
>     writeln("found 3 or 5 at ", res);
> }
>

I was going to say that the break statement only works with for loops,  
while loops and switch statments, not foreach. But the spec says  
otherwise: "A break exits the enclosing statement. break exits the  
innermost enclosing while, for, foreach, do, or switch statement, resuming  
execution at the statement following it."

However, please remember that with opApply, the foreach body gets  
converted into a delegate and then all the standard delegate rules apply.  
Which is my point: right now these rules regarding foreach seem to have  
succumb to spec-rot (i.e. they haven't been re-evaluated based on the  
introduction of opApply.


More information about the Digitalmars-d mailing list