digitalmars.D.learn - Source expression passed to a lazy parameter
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (11/11) Apr 09 2018 Is it possible to get the source expression sent to a lazy
- Basile B. (3/14) Apr 09 2018 No (afaik), what you need is an internal compiler function,
- Jonathan M Davis (16/27) Apr 09 2018 Given how lazy parameters work, I don't see how that would be possible. ...
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (50/52) Apr 09 2018 Nope. Something along the lines of __traits(getSource, arg) has
- Alex (3/5) Apr 09 2018 Is this available somehow? And/or do you have a link to the
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (7/12) Apr 09 2018 https://forum.dlang.org/post/huyqfcoosgzfneswnrur@forum.dlang.org
- Seb (3/16) Apr 09 2018 For reference, the most recent discussion and PR is
- Stefan Koch (13/24) Apr 09 2018 Because of the way D works with a given piece of code may not
Is it possible to get the source expression sent to a lazy
function?
So that I can implement something like
show(Arg)(lazy Arg arg)
{
writeln(arg.sourceof, arg);
}
used as
show(1+2+3);
will print
1+2+3:6
Apr 09 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?
So that I can implement something like
show(Arg)(lazy Arg arg)
{
writeln(arg.sourceof, arg);
}
used as
show(1+2+3);
will print
1+2+3:6
No (afaik), what you need is an internal compiler function,
"toChars" IIRC, that's available for each node.
Apr 09 2018
On Monday, April 09, 2018 08:27:50 Per Nordlöw via Digitalmars-d-learn
wrote:
Is it possible to get the source expression sent to a lazy
function?
So that I can implement something like
show(Arg)(lazy Arg arg)
{
writeln(arg.sourceof, arg);
}
used as
show(1+2+3);
will print
1+2+3:6
Given how lazy parameters work, I don't see how that would be possible. lazy
parameters are implemented as delegates, and the function doesn't have
access to what the argument was, just the delegate to get the result of
evaluating it. Functions with lazy parameters don't have to be templates,
and if the function is a template, as long as the type of the expression is
the same, it should only result in one instantiation of the function
template. As such, the only way that something like what you're suggesting
would work would be if there were some way to get the string representation
of the body of a delegate at runtime, and that would be pretty much the same
as getting the string representation of any function at runtime. That sort
of thing simply isn't kept around beyond what's required to compile the
function in the first place. The closest that you'd get would be whatever
comes with debug symbols when they're enabled.
- Jonathan M Davis
Apr 09 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
Apr 09 2018
On Monday, 9 April 2018 at 09:20:42 UTC, Simen Kjærås wrote:Nope. Something along the lines of __traits(getSource, arg) has been discussed occasionally.Is this available somehow? And/or do you have a link to the discussion, maybe?
Apr 09 2018
On Monday, 9 April 2018 at 11:33:56 UTC, Alex wrote:On Monday, 9 April 2018 at 09:20:42 UTC, Simen Kjærås wrote:https://forum.dlang.org/post/huyqfcoosgzfneswnrur forum.dlang.org https://github.com/dlang/dmd/pull/953 I'm pretty sure there have been other discussions too, but a brief search yielded too many irrelevant results. -- SimenNope. Something along the lines of __traits(getSource, arg) has been discussed occasionally.Is this available somehow? And/or do you have a link to the discussion, maybe?
Apr 09 2018
On Monday, 9 April 2018 at 13:03:38 UTC, Simen Kjærås wrote:On Monday, 9 April 2018 at 11:33:56 UTC, Alex wrote:For reference, the most recent discussion and PR is https://github.com/dlang/dmd/pull/7821 (it's currently orphaned)On Monday, 9 April 2018 at 09:20:42 UTC, Simen Kjærås wrote:https://forum.dlang.org/post/huyqfcoosgzfneswnrur forum.dlang.org https://github.com/dlang/dmd/pull/953 I'm pretty sure there have been other discussions too, but a brief search yielded too many irrelevant results. -- SimenNope. Something along the lines of __traits(getSource, arg) has been discussed occasionally.Is this available somehow? And/or do you have a link to the discussion, maybe?
Apr 09 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?
So that I can implement something like
show(Arg)(lazy Arg arg)
{
writeln(arg.sourceof, arg);
}
used as
show(1+2+3);
will print
1+2+3:6
Because of the way D works with a given piece of code may not
have a source-location or even a representation which is valid D
source code.
Note: There is a way to fix this but it's very involved.
Step 1: you use cow (copy-on-write) when modifying AST nodes in
semantic() or you keep distinct trees.
Step 2: you sanitize implicitly generated code to make sure it's
actually valid code.
Step 3: you write the generated code, to a well-defined location
such that source-of can point to a valid location.
also note that support for sourceof at compiletime will bloat the
executable since it needs to store the source-text.
Apr 09 2018









Basile B. <b2.temp gmx.com> 