www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Suggestion for a new trait: __traits(getCaptures,...)

reply Zoadian <no no.no> writes:
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
Oct 22 2019
next sibling parent Max Haughton <maxhaton gmail.com> writes:
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.
Oct 22 2019
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
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]));
Oct 22 2019
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
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.
Oct 22 2019
prev sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
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.
Oct 22 2019