Source expression passed to a lazy parameter
Simen Kjærås
simen.kjaras at gmail.com
Mon Apr 9 09:20:42 UTC 2018
On Monday, 9 April 2018 at 08:27:50 UTC, Per Nordlöw wrote:
> Is it possible to get the source expression sent to a lazy
> function?
Nope. Something along the lines of __traits(getSource, arg) has
been discussed occasionally.
For lazy what you're asking is impossible, since the compiler
doesn't know which actual arguments have been passed. show(1+2)
will look absolutely identical to show(3), will look identical to
show(myVarWithValue3).
Now, there are some things you can do. Notably, lambdas are
included verbatim in templated type names, which we can exploit.
struct S(alias fn) {}
void show(alias fn)() {
import std.stdio;
writeln(S!fn.stringof[18..$-1], ": ", fn());
}
unittest {
show!(()=>1+2); // prints "3: 3"
}
As we can see, it optimizes '1+2' to become 3, so it's not
perfect.
This also works for lambdas that include local variables:
unittest {
int i = 13;
show!(() => i+2); // Prints "i + 2: 15"
}
However, it fails for lambdas that take arguments:
struct S(alias fn) {}
void show(alias fn, T...)(T args) {
import std.stdio;
writeln(S!fn.stringof[18..$-1], ": ", fn(args));
}
unittest {
show!(a => a+2)(3); // Fails to compile
}
The reason this fails is the lambda's textual representation
decays to '__lambda1'.
There is however still something we can do, but things get even
less flexible:
struct show(alias fn) {
static void opCall(T...)(T args) {
import std.stdio, std.string;
enum s = show.stringof;
enum i = s.indexOf("=>");
writeln(s[i+3..$-1], ": ", fn(args));
}
}
unittest {
show!(a => a+2)(3); // Prints "a + 2: 5"
}
--
Simen
More information about the Digitalmars-d-learn
mailing list