Thread overview
Suggestion for a new trait: __traits(getCaptures,...)
Oct 22, 2019
Zoadian
Oct 22, 2019
Max Haughton
Oct 22, 2019
Paul Backus
Oct 22, 2019
Adam D. Ruppe
Oct 23, 2019
rikki cattermole
October 22, 2019
Hello!

I tried to implement a reactivity pattern similar to vue.js and ran into the problem that it currently is not possible (correct me if I am wrong) to find out which variables are implicitly captured or accessed in lambdas/member functions.
Would it be possible to add this to D? `Would it require a DIP?

Example how i would imagine it:
```
struct S{ int b; }
int a;
S s;

auto fun = (){ return a + s.b; }

alias vars = __traits(getCaptures, fun);

assert_alias(vars[0] == a, vars[1] == s.b);
```

I have a quick and dirty implementation here (it's not good, just POC): https://github.com/Zoadian/dmd/commit/5a4f2f2705d491aa4ce0ae2ea7721f9340cb3d7f

Greetings
Zoadian
October 22, 2019
On Tuesday, 22 October 2019 at 14:26:49 UTC, Zoadian wrote:
> Hello!
>
> I tried to implement a reactivity pattern similar to vue.js and ran into the problem that it currently is not possible (correct me if I am wrong) to find out which variables are implicitly captured or accessed in lambdas/member functions.
> Would it be possible to add this to D? `Would it require a DIP?
>
> Example how i would imagine it:
> ```
> struct S{ int b; }
> int a;
> S s;
>
> auto fun = (){ return a + s.b; }
>
> alias vars = __traits(getCaptures, fun);
>
> assert_alias(vars[0] == a, vars[1] == s.b);
> ```
>
> I have a quick and dirty implementation here (it's not good, just POC): https://github.com/Zoadian/dmd/commit/5a4f2f2705d491aa4ce0ae2ea7721f9340cb3d7f
>
> Greetings
> Zoadian

I'd never thought about that one before, good idea.

We need a much wider and deeper traits system.

October 22, 2019
On Tuesday, 22 October 2019 at 14:26:49 UTC, Zoadian wrote:
> Example how i would imagine it:
> ```
> struct S{ int b; }
> int a;
> S s;
>
> auto fun = (){ return a + s.b; }
>
> alias vars = __traits(getCaptures, fun);
>
> assert_alias(vars[0] == a, vars[1] == s.b);
> ```

Rather than a new `__traits`, it would also suffice to add a `.captures` property to delegates. Then we could write the following:

int a;
auto fun = () { return a; };
assert(__traits(isSame, a, fun.captures[0]));
October 22, 2019
On Tuesday, 22 October 2019 at 16:42:36 UTC, Paul Backus wrote:
> Rather than a new `__traits`, it would also suffice to add a `.captures` property to delegates. Then we could write the following:

That won't work since the type system doesn't know delegate origins; whether it is a capture or an object or whatever is lost.

Though perhaps we could extend it... so the delegate's actual type DOES store this info, and then it implicitly casts back to the naked delegate we have today. That might be very interesting, then templates could possibly do by-value passes too.
October 23, 2019
On 23/10/2019 5:42 AM, Paul Backus wrote:
> On Tuesday, 22 October 2019 at 14:26:49 UTC, Zoadian wrote:
>> Example how i would imagine it:
>> ```
>> struct S{ int b; }
>> int a;
>> S s;
>>
>> auto fun = (){ return a + s.b; }
>>
>> alias vars = __traits(getCaptures, fun);
>>
>> assert_alias(vars[0] == a, vars[1] == s.b);
>> ```
> 
> Rather than a new `__traits`, it would also suffice to add a `.captures` property to delegates. Then we could write the following:
> 
> int a;
> auto fun = () { return a; };
> assert(__traits(isSame, a, fun.captures[0]));

This would require a DIP, adding a trait however would not.