blocks with attributes vs inlined lambda
monarch_dodra
monarchdodra at gmail.com
Mon Jun 17 12:05:05 PDT 2013
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.
# 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.
# 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...
----------------
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've decided to write a DIP for this.
More information about the Digitalmars-d
mailing list