Re: Source expression passed to a lazy parameter

2018-04-09 Thread Seb via Digitalmars-d-learn

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:

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?


https://forum.dlang.org/post/huyqfcoosgzfneswn...@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.


--
  Simen


For reference, the most recent discussion and PR is 
https://github.com/dlang/dmd/pull/7821 (it's currently orphaned)


Re: Source expression passed to a lazy parameter

2018-04-09 Thread Stefan Koch via Digitalmars-d-learn

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.


Re: Source expression passed to a lazy parameter

2018-04-09 Thread Simen Kjærås via Digitalmars-d-learn

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:
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?


https://forum.dlang.org/post/huyqfcoosgzfneswn...@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.


--
  Simen


Re: Source expression passed to a lazy parameter

2018-04-09 Thread Alex via Digitalmars-d-learn

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?




Re: Source expression passed to a lazy parameter

2018-04-09 Thread Simen Kjærås via Digitalmars-d-learn

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


Re: Source expression passed to a lazy parameter

2018-04-09 Thread Jonathan M Davis via Digitalmars-d-learn
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




Re: Source expression passed to a lazy parameter

2018-04-09 Thread Basile B. via Digitalmars-d-learn

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.