Delegate Literals + Immutability, pure and closures

Steven Schveighoffer schveiguy at yahoo.com
Thu Sep 29 13:48:31 PDT 2011


On Thu, 29 Sep 2011 16:32:45 -0400, dsimcha <dsimcha at yahoo.com> wrote:

> Immutability and type propagation are two of D's greatest assets.  Below  
> is an
> example of where they would be difficult to take advantage of:
>
> int foo;
> if( bar < 3) {
>     try {
>         foo = doStuff(someOtherStackVariables);
>     } catch(SomeException) {
>         foo = 666;
>     }
> } else {
>     foo = 4;
> }
>
> I've recently discovered this pattern to allow use of type propagation  
> and
> immutability in these situations with no extra boilerplate:
>
> immutable foo = {
>     if( bar < 3) {
>         try {
>             return doStuff(someOtherStackVariables);
>         } catch(SomeException) {
>             return 666;
>         }
>     } else {
>         return 4;
>     }
> }();
>
> This allows me to make foo immutable and have its type inferred while  
> avoiding
> any boilerplate code, but has four problems:
>
> 1.  It allocates a closure.  Therefore, it can't be used in
> performance-critical code.  We really need to optimize away closure  
> allocation
> in trivial cases where the function pointer obviously can't escape, to  
> make
> delegate literals more useful in performance-critical code.
>
> 2.  Delegate literals can't be inlined in even the most trivial cases.   
> This
> is less severe than (1), and probably would almost never have a  
> non-negligible
> impact in practice, though.
>
> 3.  A function that uses a delegate literal can't be pure because purity  
> is
> not inferred for delegate literals:
>
> void main() {
>     foo();
> }
>
> void foo() pure {
>     int z;
>     int i = {return z + 1;}();
> }
>
> Error: pure function 'foo' cannot call impure delegate '__dgliteral1'
>
> 4.  Auto return type inference is limited to cases where all return  
> statements
> return the exact type.  Is there any reason I'm missing why, if multiple
> return statements with different types are present, an auto return  
> function
> couldn't just return a common type?

+1 on all 4 issues.

Note that there is a workaround for 1:

DT noclosure(DT)(scope DT d) if(is(DT == delegate))
{
   return d;
}

Also note that next to memory allocation, lack of inlining is the biggest  
performance problem.  It's not negligible (in case that is what you were  
saying, hard to tell from all the negatives ;)

-Steve


More information about the Digitalmars-d mailing list