www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does stringof not like functions with arguments?

reply Jason Brady <evervision hotmail.com> writes:
Why does the following code error out with:

app.d(12,10): Error: function app.FunctionWithArguments (uint i) 
is not callable using argument types ()

Code:

import std.stdio;

void FunctionWithoutArguments() {
}

void FunctionWithArguments(uint i) {
}

void main()
{
	writeln(FunctionWithoutArguments.stringof);
	writeln(FunctionWithArguments.stringof);
}
Aug 08
next sibling parent Olivier FAURE <olivier.faure epitech.eu> writes:
On Wednesday, 9 August 2017 at 01:39:07 UTC, Jason Brady wrote:
 Why does the following code error out with:

 app.d(12,10): Error: function app.FunctionWithArguments (uint 
 i) is not callable using argument types ()

 Code:

 import std.stdio;

 void FunctionWithoutArguments() {
 }

 void FunctionWithArguments(uint i) {
 }

 void main()
 {
 	writeln(FunctionWithoutArguments.stringof);
 	writeln(FunctionWithArguments.stringof);
 }
I'm not sure how `stringof` actually works, but it expects a valid expression as its prefix. `FunctionWithoutArguments` is a valid expression (optional parentheses), but `FunctionWithArguments` is not.
Aug 09
prev sibling next sibling parent Biotronic <simen.kjaras gmail.com> writes:
On Wednesday, 9 August 2017 at 01:39:07 UTC, Jason Brady wrote:
 Why does the following code error out with:

 app.d(12,10): Error: function app.FunctionWithArguments (uint 
 i) is not callable using argument types ()
Like Olivier said, stringof expects a valid expression. There are a few other options: module foo; import std.traits; pragma(msg, bar(3).stringof); // prints "bar(3)" pragma(msg, (&bar).stringof); // "& bar" pragma(msg, fullyQualifiedName!bar); // "foo.bar" pragma(msg, __traits(identifier, bar)); // "bar" void bar(int n) {}
Aug 09
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Wednesday, 9 August 2017 at 01:39:07 UTC, Jason Brady wrote:
 Why does the following code error out with:

 app.d(12,10): Error: function app.FunctionWithArguments (uint 
 i) is not callable using argument types ()

 Code:

 import std.stdio;

 void FunctionWithoutArguments() {
 }

 void FunctionWithArguments(uint i) {
 }

 void main()
 {
 	writeln(FunctionWithoutArguments.stringof);
 	writeln(FunctionWithArguments.stringof);
 }
Welcome to optional parentheses hell. Please enjoy your stay. Because function calls in D can optionally omit the parens, `FunctionWithArguments.stringof` is actually attempting to call `FunctionWithArguments` without any arguments, and then call `stringof` on the result. In other words, it's actually trying to do this: writeln(FunctionWithArguments().stringof); And the D compiler is rightly telling you that you can't call the function with no arguments. The easiest solution is to use __traits(identifier) instead: writeln(__traits(identifier, FunctionWithArguments)); You can make a handy template helper to do this for you: enum stringOf(alias symbol) = __traits(identifier, symbol); writeln(stringOf!FunctionWithArguments);
Aug 10
parent reply Jason Brady <evervision hotmail.com> writes:
On Thursday, 10 August 2017 at 14:51:22 UTC, Meta wrote:
 Welcome to optional parentheses hell. Please enjoy your stay.

 Because function calls in D can optionally omit the parens, 
 `FunctionWithArguments.stringof` is actually attempting to call 
 `FunctionWithArguments` without any arguments, and then call 
 `stringof` on the result. In other words, it's actually trying 
 to do this:

 writeln(FunctionWithArguments().stringof);

 And the D compiler is rightly telling you that you can't call 
 the function with no arguments. The easiest solution is to use 
 __traits(identifier) instead:

 writeln(__traits(identifier, FunctionWithArguments));

 You can make a handy template helper to do this for you:

 enum stringOf(alias symbol) = __traits(identifier, symbol);
 writeln(stringOf!FunctionWithArguments);
Wow. That makes perfect sense. I forgot stringof works only with expressions and that a function name is a valid expression in the case of UCF. I already found the __traits as a workaround, but the template helper is a great idea. Thanks!
Aug 10
parent Meta <jared771 gmail.com> writes:
On Thursday, 10 August 2017 at 15:55:41 UTC, Jason Brady wrote:
 Wow. That makes perfect sense. I forgot stringof works only 
 with expressions
It works with symbols too. See the following: template test(){} pragma(msg, test.stringof);
Aug 10