digitalmars.D - Idea: Context sensitive attribute functions.
- 12345swordy (18/18) Jun 19 2018 Pseudocode:
- Dennis (14/15) Jun 19 2018 You can do that if you want
- Dennis (19/22) Jun 19 2018 Although it doesn't seem to work in attribute interference of
- Jonathan M Davis (14/37) Jun 19 2018 Whether a function is @nogc has nothing to do with where it's called fro...
- Dennis (26/29) Jun 19 2018 Indeed, I realised that the same template instantiation can't
- Jonathan M Davis (15/44) Jun 19 2018 Hmm. That's clever, but that approach would not work very well with func...
- 12345swordy (6/21) Jun 20 2018 No, it is not the same. You are testing one of the rules that is
Pseudocode: void example() { static if(Context = nogc) { //nogc implementation } else { //gc implementation } } This is useful as it eliminate the need to create multiple functions for each possible system attribute hence reducing redundant code. There are advantages of having a gc/unsafe/throw code. Why not use them if given the opportunity based on its context? - Alex
Jun 19 2018
On Tuesday, 19 June 2018 at 19:03:44 UTC, 12345swordy wrote:Why not use them if given the opportunity based on its context?You can do that if you want ``` import std.stdio; import core.stdc.stdio; void main() nogc { int a = 8; static if (__traits(compiles, new int(0))) { writefln("writeln %d", a); } else { printf("printf %d", a); } } ```
Jun 19 2018
On Tuesday, 19 June 2018 at 21:06:16 UTC, Dennis wrote:On Tuesday, 19 June 2018 at 19:03:44 UTC, 12345swordy wrote:Although it doesn't seem to work in attribute interference of templates. ``` void main() nogc { example(); } void example()() { int a = 8; static if (__traits(compiles, new int(0))) { writefln("writeln %d", a); } else { printf("printf %d", a); } } ``` onlineapp.d(5): Error: nogc function D main cannot call non- nogc function onlineapp.example!().example Maybe there's some workaround?Why not use them if given the opportunity based on its context?You can do that if you want
Jun 19 2018
On Tuesday, June 19, 2018 21:11:10 Dennis via Digitalmars-d wrote:On Tuesday, 19 June 2018 at 21:06:16 UTC, Dennis wrote:Whether a function is nogc has nothing to do with where it's called from. It has to do with what it calls. As such, new int(0) compiles just fine inside of your example function, and that branch is compiled in, making it so that the function is not nogc. I am not aware of any way to make a function's attributes depend on what calls it. The closest would be if you changed what it did based on its template arguments - which would mean doing something like passing a bool or flag indicating whether the function should be compiled as nogc or not. I don't think that it's possible to have a function be compiled differently based on where it's called from. Attribute inference is all about inferring the attributes of the templated function based on its implementation, not adjusting its implementation based on where it's used. - Jonathan M DavisOn Tuesday, 19 June 2018 at 19:03:44 UTC, 12345swordy wrote:Although it doesn't seem to work in attribute interference of templates. ``` void main() nogc { example(); } void example()() { int a = 8; static if (__traits(compiles, new int(0))) { writefln("writeln %d", a); } else { printf("printf %d", a); } } ``` onlineapp.d(5): Error: nogc function D main cannot call non- nogc function onlineapp.example!().example Maybe there's some workaround?Why not use them if given the opportunity based on its context?You can do that if you want
Jun 19 2018
On Tuesday, 19 June 2018 at 21:38:14 UTC, Jonathan M Davis wrote:Attribute inference is all about inferring the attributes of the templated function based on its implementation, not adjusting its implementation based on where it's used.Indeed, I realised that the same template instantiation can't possibly have both a nogc and gc version, so there has to be a template parameter. You can automatically set one however: ``` void main() nogc { example(); } void example(string callee = __FUNCTION__)() { int a = 8; static if (isNoGc!callee) { printf("printf %d", a); } else { writefln("writeln %d", a); } } bool isNoGc(string functionName)() { import std.algorithm; mixin(`return [__traits(getFunctionAttributes, `~functionName~`)].canFind(" nogc");`); } ``` This seems to work. I'm not sure how robust it is though. You might need an extra `mixin("import "~functionName~";");` in `isNoGc` when it's called from other modules (if that helps at all).
Jun 19 2018
On Tuesday, June 19, 2018 22:22:23 Dennis via Digitalmars-d wrote:On Tuesday, 19 June 2018 at 21:38:14 UTC, Jonathan M Davis wrote:Hmm. That's clever, but that approach would not work very well with function overloads. Also, it falls apart on some level if the caller is a template function that relies on attribute inference to be nogc. In such cases, the caller would be infered as not being nogc, and example would be compiled with the GC version. In addition, even if it all worked perfectly, it would mean compiling a different instantation of the function for every function that calls it, which seems likely to cause an awful lot of bloat. It's not as bad as using __FILE__ and __LINE__ as template arguments, but it's close. Another problem here is that as long as we can't introspect on private members of other modules (which really should be fixed), this would likely fail to compile when the caller is private and in another module. But hopefully, that's just a temporary issue. Making it deal with overloads correctly is likely a far bigger issue long term. - Jonathan M DavisAttribute inference is all about inferring the attributes of the templated function based on its implementation, not adjusting its implementation based on where it's used.Indeed, I realised that the same template instantiation can't possibly have both a nogc and gc version, so there has to be a template parameter. You can automatically set one however: ``` void main() nogc { example(); } void example(string callee = __FUNCTION__)() { int a = 8; static if (isNoGc!callee) { printf("printf %d", a); } else { writefln("writeln %d", a); } } bool isNoGc(string functionName)() { import std.algorithm; mixin(`return [__traits(getFunctionAttributes, `~functionName~`)].canFind(" nogc");`); } ``` This seems to work. I'm not sure how robust it is though. You might need an extra `mixin("import "~functionName~";");` in `isNoGc` when it's called from other modules (if that helps at all).
Jun 19 2018
On Tuesday, 19 June 2018 at 21:06:16 UTC, Dennis wrote:On Tuesday, 19 June 2018 at 19:03:44 UTC, 12345swordy wrote:No, it is not the same. You are testing one of the rules that is defined by the attribute, you are not testing the attribute itself that is derived by the context that you are in. You code can't take into account of custom attributes. AlexanderWhy not use them if given the opportunity based on its context?You can do that if you want ``` import std.stdio; import core.stdc.stdio; void main() nogc { int a = 8; static if (__traits(compiles, new int(0))) { writefln("writeln %d", a); } else { printf("printf %d", a); } } ```
Jun 20 2018