Lambda surprise
Jean-Louis Leroy
jl at leroy.nyc
Sat Feb 8 06:21:50 UTC 2020
While implementing support for parameter storage classes in my
openmethods library, I ran into a puzzling error.
While massaging code I came up with something like this:
// dmd -c surprise.d
import std.algorithm;
import std.range;
struct Method {
static string foo() {
enum foo = [ "a", "b" ].map!(x => x ~ x).join(":");
return foo;
}
}
pragma(msg, Method.foo()); // aa:bb
Now this is clearly a compile time constant, so I thought I would
make it simpler and more explicit:
struct Method {
enum foo = [ "a", "b" ].map!(x => x ~ x).join(":");
}
...which got me this error:
/home/jll/dlang/dmd-2.085.0/linux/bin64/../../src/phobos/std/algorithm/iteration.d(475): Error: `this.__lambda2` has no value
It took me a while to realize that the root of the problem was
that the lambda was trying to capture `this`. While fiddling I
threw in a `static` in front of `enum`:
struct Method {
static enum foo = [ "a", "b" ].map!(x => x ~ x).join(":");
}
...and I got a more useful error message:
/home/jll/dlang/dmd-2.085.0/linux/bin64/../../src/phobos/std/algorithm/iteration.d(470): Error: function `surprise.Method.map!((x) => x ~ x).map!(string[]).map` need `this` to access member `map`
Thus the first version works because the lambda is formed inside
a static method. This works as well:
struct Method {
static string stutter(string s) { return s ~ s; }
enum foo = [ "a", "b" ].map!(stutter).join(":");
}
I wonder:
1/ Could the error message could be made more explicit in my
first attempt at making the expression an `enum`?
2/ Is the lambda capturing `this` inside a class, even if it is
not referenced, a documented behavior? Is it the right thing to
do?
More information about the Digitalmars-d
mailing list