non-lambda overloads for lambda-only things

tsbockman thomas.bockman at gmail.com
Fri Apr 16 20:25:27 UTC 2021


On Friday, 16 April 2021 at 11:23:07 UTC, Jacob Carlborg wrote:
> BTW, what's stopping us from supporting the above syntax? Why 
> do we still pass the lambda as a template argument? In that 
> past, before proper support for lambdas, there was a use case 
> to pass a string literal, which must be passed as a template 
> argument. If DMD cannot inline the lambda, who cares, use LDC 
> instead.

When a function or delegate is passed as a runtime argument, it 
cannot be inlined unless the function it is being passed to is 
also inlined. But, when one is passed as a template argument it 
can be inlined even if the function receiving it cannot or should 
not be inlined.

This limitation is fundamental to the language, not a weakness of 
any particular implementation:

```D
module app;

auto fRT(int function(int) g, int x) {
     pragma(inline, false); // For demonstration purposes.
     return g(x * 7);
}
auto fCT(alias g)(int x)
     if(is(typeof(g) : int function(int)))
{
     pragma(inline, false); // For demonstration purposes.
     return g(x * 7);
}

void main() {
     import std.stdio : writeln;

     /* g cannot be inlined in fRT,
     because g may be different every time f is called: */
     writeln(fRT((int y) { return y + 3; }, 4));
     writeln(fRT((int y) { return y - 2; }, 2));

     /* But, g can be inlined in some possible instantiations of 
fCT,
     because each instantiation is a separate function at runtime: 
*/
     writeln(fCT!((int y) { return y + 3; })(4));
     writeln(fCT!((int y) { return y - 2; })(2));
}
```
Part of the resulting assembly code with LDC `-m64 -mcpu=haswell 
-O3 -release`:
```
int app.fRT(int function(int)*, int):
         lea     eax, [8*rdi]
         sub     eax, edi
         mov     edi, eax
         jmp     rsi

pure nothrow @nogc @safe int 
app.fCT!(app.main().__lambda3(int)).fCT(int):
         lea     eax, [8*rdi]
         sub     eax, edi
         add     eax, 3
         ret

pure nothrow @nogc @safe int 
app.fCT!(app.main().__lambda4(int)).fCT(int):
         lea     eax, [8*rdi]
         sub     eax, edi
         add     eax, -2
         ret
```


More information about the Digitalmars-d mailing list