blocks with attributes vs inlined lambda

Kenji Hara k.hara.pg at gmail.com
Tue Jun 18 00:57:51 PDT 2013


2013/6/18 monarch_dodra <monarchdodra at gmail.com>

> On Saturday, 8 June 2013 at 15:56:47 UTC, deadalnix wrote:
>
>> On Saturday, 8 June 2013 at 14:52:23 UTC, monarch_dodra wrote:
>>
>> Sound like a nice idiom. Why is the first set of () needed ? Can we
>> change the grammar to remove them ?
>>
>
> I've been playing around with this idiom some more, and found some pretty
> serious limitations:
>
> # Scoped block:
> Using a lambda functions creates a new scope. Having a "true" labeled
> block, just like static ifs, should not create a new scope. This is
> relevant if you want to make sure a constructor or destructor is nothrow,
> for example (destructor could be handled via a simple attribute followed by
> a colon. eg:
>
> void foo()
> {
>     nothrow {
>         Sentinel s; //declare sentinel
>     }
>
>     code_goes_here
>
>     nothrow:
>         clean_up_goes_here_code
>         destructors_are_nothrow
> }
>
> A lambda would not allow these two constructs.
>

In D, variable declaration with default construction is always nothrow.
So, enclosing the declaration of s by nothrow block is unnecessary.

For nothrow destruction, you can add following static assert in foo().

    static assert(__traits(compiles, ()nothrow{ Sentinel s; }), "Sentinel
dtor is not nothrow");

# Purity
> Because a lambda needs to access the frame, any function using the lambda
> trick can't be made pure:
> void foo(T)(T a) @safe
> {
>     (){
>         ++a;
>     }();
> }
> Error: pure function 'main.foo' cannot call impure function literal
> '__lambda1'
>
> The workaround is to explicitly pass the arguments, *preferably*,
> shadowing them for clarity:
> void foo(int a) pure
> {
>     (ref int a){
>         ++a;
>     }(a);
> }
> This is already *much* less convenient. Imagine if the block needed to
> access 3, 5 or even more variabes ! Also, if one of those variables is
> declared as "auto", then you bring in the "ref typeof(a) a" ugliness. Just
> no.


This is a compiler bug, and I recently fixed it in git master. Explicit
argument passing does not need anymore.


> # Performance
> I haven't actually tested this one, but I'd be inclined to think there is
> a performance hit for non-release and non-inline builds. inline builds
> *may* optimize it away, but I'm not sure...
>

Inlining should remove performance penalty. Nobody holds the immediately
called lambda, so it should be treated as a 'scope delegate'. For that, we
would need to add a section in language spec to support it.


> ----------------
> So my conclusion is that the lambda tric is a partial workaround. We'd
> need real support for being able to have specific qualification inside
> bodies.
>

I don't think so. We can sufficiently use lambda for the "attribute block".

Kenji Hara
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20130618/16a2ce4d/attachment-0001.html>


More information about the Digitalmars-d mailing list