www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - alternate foreach semantics proposal

reply BCS <ao pathlink.com> writes:
When I am writing integrators, I keep finding my self writing function of 
this pattern:

|class C
|{
|  int delegate(int delegate(inout T)) Fn(Args args)
|  {
|    struct S
|    {
|      Args a;
|      int fn(int delegate(inout T) dg)
|      {
|        // loop using a for filtering/order/etc.
|          if(int ret = dg(i))
|            return ret;
|        return 0;
|      }
|    }
|    auto ret = new S;
|    ret.args = args
|    return &ret.fn;
|  }
|}

genealy it gets used like this

|C c = new C;
|foreach(T t; c.Fn(args)) {...}

This does a new and the almost first thing, drops the struct. It would be 
really nice if this could be rearranged like this:

|class C
|{
|  int Fn(int delegate(inout T), Args args)
|  {
|    // loop using args for filtering/order/etc.
|      if(int ret = dg(i))
|        return ret;
|    return 0;
|  }
|}

C c = new C;
foreach(T t; c.Fn(args)) {...}

The foreach would allow a function where the first parameter is a "int
delegate(inout 
T)" to be used as an literator and have the other parameters passed from 
the "invocation".
Apr 13 2007
parent BCS <ao pathlink.com> writes:
On second thought, that syntax wouldn't work to well. For one it generates 
an ambiguity between

int dg(int dg(inout T)) Fn(Args...)
and 
int Fn(int dg(inout T), Args...)

A better choice would be to have this form of foreach:

foreach(inout T; c.It, Args...)

call the named function with the body delegate and the provided args. There 
isn't an ambiguity here because, given that the current form can't have args 
after the iterated symbol, the args list would clearly identify that the 
`extended call' form should be used rather than the `call and return delegate' 
form.

Reply to Benjamin,
[...]
 |class C
 |{
 |  int Fn(int delegate(inout T), Args args)
 |  {
 |    // loop using args for filtering/order/etc.
 |      if(int ret = dg(i))
 |        return ret;
 |    return 0;
 |  }
 |}

 |C c = new C;
 |foreach(T t; c.Fn(args)) {...}

 The foreach would allow a function where the first parameter is a "int
 delegate(inout T)" to be used as an literator and have the other
 parameters passed from the "invocation".
 
Apr 15 2007