www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is this a new bug ?

reply Newbie2019 <newbie2019 gmail.com> writes:
template Test(alias T){
         pragma(msg, T.stringof);
         enum Test = T.stringof;
}

string t1;
void t2(){}
void t3(string s){}

extern(C) void  main(){
         enum x1 = Test!(t1); // ok
         enum x2 = Test!(t2); //   expect t2,  but get t2()
         enum x3 = Test!(t3); //    Error: function 
test2.t3(string s) is not callable using argument types ()
}


I want get the function name "t2", "t3" for string mixin,  how do 
I do this in D ?
Jul 19 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 20 July 2019 at 03:31:41 UTC, Newbie2019 wrote:
 template Test(alias T){
         pragma(msg, T.stringof);
Believe it or not, but this can result in the function being called. This is D's optional parenthesis feature, to do simple property syntax. Not a bug.
 I want get the function name "t2", "t3" for string mixin,  how 
 do I do this in D ?
You should never actually need that! What is your use case? In most cases I see people doing .stringof, the correct solution is to simply... not. Use the local name directly. If you do need the name - and the only cases for this ought to be declaring a new item for public consumption or for interfacing with users - the correct way to get an identifier is `__traits(identifier, T)`... but again, more often than not, you do NOT need this and it is wrong to try! .stringof should almost never be used except for debugging, and string concatenation in string mixings is actually only necessary for new declaration names. OK: mixin("int " ~ name ~ " = T;"); Wrong: mixin("int " ~ name ~ " = " ~ T.stringof ~ ";");
Jul 19 2019
parent reply Newbie2019 <newbie2019 gmail.com> writes:
On Saturday, 20 July 2019 at 03:58:36 UTC, Adam D. Ruppe wrote:
 You should never actually need that! What is your use case?

 In most cases I see people doing .stringof, the correct 
 solution is to simply... not. Use the local name directly.

 If you do need the name - and the only cases for this ought to 
 be declaring a new item for public consumption or for 
 interfacing with users - the correct way to get an identifier 
 is `__traits(identifier, T)`... but again, more often than not, 
 you do NOT need this and it is wrong to try!

 .stringof should almost never be used except for debugging, and 
 string concatenation in string mixings is actually only 
 necessary for new declaration names.

 OK:

 mixin("int " ~ name ~ " = T;");

 Wrong:

 mixin("int " ~ name ~ " = " ~ T.stringof ~ ";");
Thanks very much, __traits(identifier, Fn) is what I need. I may not fully understand why I can done it without identifier.stringof, I also need this string mixin for code and debug. so I just go with __traits(identifier, Fn) right now.
Jul 19 2019
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 20 July 2019 at 04:10:53 UTC, Newbie2019 wrote:
 I may not fully understand why I can done it without 
 identifier.stringof
show me what you're doing now and I'll see which case it is. Most the time I see these, the code is significantly simplified and bugs fixed by removing the usages of these strings..
Jul 19 2019
parent reply Newbie2019 <newbie2019 gmail.com> writes:
On Saturday, 20 July 2019 at 04:18:15 UTC, Adam D. Ruppe wrote:
 show me what you're doing now and I'll see which case it is. 
 Most the time I see these, the code is significantly simplified 
 and bugs fixed by removing the usages of these strings..
I want to do this in betterC: template asPure(string P, alias Fn) if (isFunctionPointer!(typeof(&Fn))) { enum N = __traits(identifier, Fn); enum string asPure = "private alias " ~ N ~ "_P = " ~ typeof(&Fn).stringof ~ " pure;\n" ~ "__gshared immutable " ~ N ~ "_P " ~ P ~"= cast(" ~ N ~ "_P) &" ~ N ~ " ;" ; }
Jul 19 2019
parent reply user1234 <user1234 12.de> writes:
On Saturday, 20 July 2019 at 05:21:01 UTC, Newbie2019 wrote:
 On Saturday, 20 July 2019 at 04:18:15 UTC, Adam D. Ruppe wrote:
 show me what you're doing now and I'll see which case it is. 
 Most the time I see these, the code is significantly 
 simplified and bugs fixed by removing the usages of these 
 strings..
I want to do this in betterC: template asPure(string P, alias Fn) if (isFunctionPointer!(typeof(&Fn))) { enum N = __traits(identifier, Fn); enum string asPure = "private alias " ~ N ~ "_P = " ~ typeof(&Fn).stringof ~ " pure;\n" ~ "__gshared immutable " ~ N ~ "_P " ~ P ~"= cast(" ~ N ~ "_P) &" ~ N ~ " ;" ; }
use `__traits(identifier)` instead of `.stringof`, see https://dlang.org/spec/traits.html#identifier. as explained this is not a new bug, not even a bug according to me.
Jul 19 2019
parent reply Newbie2019 <newbie2019 gmail.com> writes:
On Saturday, 20 July 2019 at 06:43:03 UTC, user1234 wrote:
 use `__traits(identifier)` instead of `.stringof`, see 
 https://dlang.org/spec/traits.html#identifier.

 as explained this is not a new bug, not even a bug according to 
 me.
I want to cast std.stdio : writefln into pure function pointer, so I can call it from debug pure function. is there a way to work around the pure check for call writefln ?
Jul 20 2019
next sibling parent reply Newbie2019 <newbie2019 gmail.com> writes:
On Saturday, 20 July 2019 at 09:01:21 UTC, Newbie2019 wrote:
 I want to cast std.stdio : writefln into pure function pointer, 
 so I can call it from debug pure function.  is there a way to 
 work around the pure check for call  writefln ?
nothrow check, not pure.
Jul 20 2019
parent Boris Carvajal <boris2.9 gmail.com> writes:
On Saturday, 20 July 2019 at 09:01:47 UTC, Newbie2019 wrote:
 On Saturday, 20 July 2019 at 09:01:21 UTC, Newbie2019 wrote:
 I want to cast std.stdio : writefln into pure function 
 pointer, so I can call it from debug pure function.  is there 
 a way to work around the pure check for call  writefln ?
nothrow check, not pure.
Use try and catch around writefln. https://run.dlang.io/is/Kv3QnT
Jul 20 2019
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 20 July 2019 at 09:01:21 UTC, Newbie2019 wrote:
 I want to cast std.stdio : writefln into pure function pointer, 
 so I can call it from debug pure function.
Like the other person said, try/catch turns throws to nothrow. The `debug` keyword disables pure checks. Those make this easy without any mixin or wrappers/casts at all. But even if you did want to do the mixin route, look at how Phobos does this. http://dpldocs.info/experimental-docs/std.traits.SetFunctionAttributes.1.html the example of that function shows adding pure to a function pointer. (and btw I think the phobos function itself works with -betterC as well, you might be able to simply call it). But then look at its implementation too: http://dpldocs.info/experimental-docs/source/std.traits.d.html#L2354 .stringof only appears once there, for the `static assert` error message. Everything else is direct stuff. It does string concat a list of keywords, but they are literally written. Then, it immediately mixes it in and thus the template returns the generated type which is used to make an alias and a cast on the outside, avoiding any mixin there too.
Jul 20 2019
parent Newbie2019 <newbie2019 gmail.com> writes:
On Saturday, 20 July 2019 at 14:19:08 UTC, Adam D. Ruppe wrote:
 Like the other person said, try/catch turns throws to nothrow. 
 The `debug` keyword disables pure checks. Those make this easy 
 without any mixin or wrappers/casts at all.

 But even if you did want to do the mixin route, look at how 
 Phobos does this.

 http://dpldocs.info/experimental-docs/std.traits.SetFunctionAttributes.1.html

 the example of that function shows adding pure to a function 
 pointer. (and btw I think the phobos function itself works with 
 -betterC as well, you might be able to simply call it).
Thanks your all for explain, now i get a better understand how pure & debug & nothrow to work together.
Jul 20 2019