Macro proposal feature request

downs default_357-line at yahoo.de
Thu Jan 3 08:37:10 PST 2008


downs wrote:
> 
>  * ALTERNATIVE PROPOSAL *
> 

Let's modify this proposal a bit.

First, let us introduce a specialization of the delegate type: dgliteral. It behaves like delegate in most ways,
with the following exceptions:
 - A dgliteral that was created from a delegate literal
   - cannot be returned from a function,
   - is implicitly constant and
   - is always inlined on call.
 - A dgliteral that was created from a delegate variable behaves as if that delegate were wrapped as follows: { return dg(); }
 - Even though they nominally share the same type, a dgliteral's complete type encodes the literal used to create
     it, as well as its return type. This is also why they cannot be reassigned.

Every dgliteral can be implicitly converted to a delegate that returns an int.
This return value signals the type of scope exit: zero for normal, one for break, two for return.
(dgliterals of course behave in the same way)
((alternatively, use symbolic constants for these))

The actual value "return"ed in the dgliteral is stored until control flow successfully re-enters the function
in which the dgliteral was created. It is then returned from the surrounding function.
The value returned may be queried and modified using the "ret" property.

Every dgliteral passed as a parameter to a function behaves as if it were a dgliteral-type template value
parameter of that function. This of course means the function cannot be inherited or used in interfaces.
A recommended way around this limitation is generating code that behaves as if the dgliteral was a simple
delegate, and fall back to this code when the precise function to be used cannot be determined
(interface/non-final class usage).

Every function that takes a dgliteral as a parameter must return an integer; this return value signals to the
calling scope in the same way that the return value of dgliteral does.

For illustration, here's an implementation of opApply using dgliteral:

class ArrayWrapper(T) {
  T[] array;
  int opApply(int dgliteral(ref T) dl) {
    foreach (ref entry; array) {
      auto res=dg(entry);
      if (res==1) return 0; // only exit the foreach scope
      if (res==2) return 2; // return is transferred to the outside scope
    }
    return 0; // normal exit
  }
}

 --downs



More information about the Digitalmars-d mailing list