www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Get the name of a function and the parameters?

reply Jacob Carlborg <doob me.com> writes:
Is it possible to get the name of a function and the names of the 
function parameters?
Apr 26 2009
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jacob Carlborg wrote:
 Is it possible to get the name of a function and the names of the
 function parameters?
I don't believe so, no. -- Daniel
Apr 26 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Daniel Keep wrote:
 
 Jacob Carlborg wrote:
 Is it possible to get the name of a function and the names of the
 function parameters?
I don't believe so, no. -- Daniel
I should perhaps qualify, in light of Jarrett's response, that I thought you meant from inside the function ala __FUNCTION__ or somesuch. -- Daniel
Apr 26 2009
parent Jacob Carlborg <doob me.com> writes:
Daniel Keep wrote:
 
 Daniel Keep wrote:
 Jacob Carlborg wrote:
 Is it possible to get the name of a function and the names of the
 function parameters?
I don't believe so, no. -- Daniel
I should perhaps qualify, in light of Jarrett's response, that I thought you meant from inside the function ala __FUNCTION__ or somesuch. -- Daniel
Jarrett's solution was exactly what I needed.
Apr 27 2009
prev sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sun, Apr 26, 2009 at 12:23 PM, Jacob Carlborg <doob me.com> wrote:
 Is it possible to get the name of a function and the names of the function
 parameters?
Name of a function? Yes. public template NameOfFunc(alias f) { version(LDC) const char[] NameOfFunc = (&f).stringof[1 .. $]; else const char[] NameOfFunc = (&f).stringof[2 .. $]; } debug { private void _foo_(){} static assert(NameOfFunc!(_foo_) == "_foo_", "Oh noes, NameOfFunc needs to be updated."); } It has to be used at compile time with an alias of course, but it works. Name of params? No, not that I've found. Sometimes the compiler will give parameter names of functions declared with tuple parameters in error messages; I wonder if that could be abused. Don't you love it? "Most C++ template features are discovered." So are D's.
Apr 26 2009
next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Jarrett Billingsley wrote:
 On Sun, Apr 26, 2009 at 12:23 PM, Jacob Carlborg <doob me.com> wrote:
 Is it possible to get the name of a function and the names of the function
 parameters?
Name of a function? Yes. public template NameOfFunc(alias f) { version(LDC) const char[] NameOfFunc = (&f).stringof[1 .. $]; else const char[] NameOfFunc = (&f).stringof[2 .. $]; } debug { private void _foo_(){} static assert(NameOfFunc!(_foo_) == "_foo_", "Oh noes, NameOfFunc needs to be updated."); } It has to be used at compile time with an alias of course, but it works. Name of params? No, not that I've found. Sometimes the compiler will give parameter names of functions declared with tuple parameters in error messages; I wonder if that could be abused. Don't you love it? "Most C++ template features are discovered." So are D's.
You can get the name of a local variable from within a scope that variable is active at compile-time. Pass it as an alias parameter and then start demangling in there; it's usually towards the end.
Apr 26 2009
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
Jarrett Billingsley wrote:
 On Sun, Apr 26, 2009 at 12:23 PM, Jacob Carlborg <doob me.com> wrote:
 Is it possible to get the name of a function and the names of the function
 parameters?
Name of a function? Yes. public template NameOfFunc(alias f) { version(LDC) const char[] NameOfFunc = (&f).stringof[1 .. $]; else const char[] NameOfFunc = (&f).stringof[2 .. $]; } debug { private void _foo_(){} static assert(NameOfFunc!(_foo_) == "_foo_", "Oh noes, NameOfFunc needs to be updated."); } It has to be used at compile time with an alias of course, but it works. Name of params? No, not that I've found. Sometimes the compiler will give parameter names of functions declared with tuple parameters in error messages; I wonder if that could be abused. Don't you love it? "Most C++ template features are discovered." So are D's.
Thanks. I found that this: void foo (int x, int y) { } void main () { pragma(msg, typeof(&foo).stringof); } gave this result: void function(int x, int y) So now I just have to get the names out of there.
Apr 27 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Mon, Apr 27, 2009 at 6:56 AM, Jacob Carlborg <doob me.com> wrote:

 I found that this:

 void foo (int x, int y)
 {
 }

 void main ()
 {
 =A0 =A0pragma(msg, typeof(&foo).stringof);
 }

 gave this result:

 void function(int x, int y)

 So now I just have to get the names out of there.
Interesting! I wonder if that changed recently.
Apr 27 2009
parent Jacob Carlborg <doob me.com> writes:
Jarrett Billingsley wrote:
 On Mon, Apr 27, 2009 at 6:56 AM, Jacob Carlborg <doob me.com> wrote:
 
 I found that this:

 void foo (int x, int y)
 {
 }

 void main ()
 {
    pragma(msg, typeof(&foo).stringof);
 }

 gave this result:

 void function(int x, int y)

 So now I just have to get the names out of there.
Interesting! I wonder if that changed recently.
I don't think so, I'm using gdc.
Apr 28 2009
prev sibling next sibling parent reply grauzone <none example.net> writes:
Jarrett Billingsley wrote:
 On Sun, Apr 26, 2009 at 12:23 PM, Jacob Carlborg <doob me.com> wrote:
 Is it possible to get the name of a function and the names of the function
 parameters?
Name of a function? Yes. public template NameOfFunc(alias f) { version(LDC) const char[] NameOfFunc = (&f).stringof[1 .. $]; else const char[] NameOfFunc = (&f).stringof[2 .. $]; } debug { private void _foo_(){} static assert(NameOfFunc!(_foo_) == "_foo_", "Oh noes, NameOfFunc needs to be updated."); } It has to be used at compile time with an alias of course, but it works.
I'd like to pass several functions at once. Is there a way to make this variadic? The obvious approach (writing "NameOfFunc(alias f...)") fails with a syntax error.
 Name of params?  No, not that I've found.  Sometimes the compiler will
 give parameter names of functions declared with tuple parameters in
 error messages; I wonder if that could be abused.
 
 Don't you love it?  "Most C++ template features are discovered."  So are D's.
Apr 28 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Apr 28, 2009 at 3:07 PM, grauzone <none example.net> wrote:
 I'd like to pass several functions at once. Is there a way to make this
 variadic? The obvious approach (writing "NameOfFunc(alias f...)") fails with
 a syntax error.
Sure, you'd just make it NameOfFunc(f...) and then recursively instantiate, converting one item at a time to its name until f.length == 0. Alternatively, you can write a compile-time map and use NameOfFunc as the mapping predicate.
Apr 28 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jarrett Billingsley wrote:
 On Tue, Apr 28, 2009 at 3:07 PM, grauzone <none example.net> wrote:
 I'd like to pass several functions at once. Is there a way to make this
 variadic? The obvious approach (writing "NameOfFunc(alias f...)") fails with
 a syntax error.
Sure, you'd just make it NameOfFunc(f...) and then recursively instantiate, converting one item at a time to its name until f.length == 0. Alternatively, you can write a compile-time map and use NameOfFunc as the mapping predicate.
That requires f to be a type, which loses you the actual names. And you cannot (last time I checked) have aliases in a tuple. -- Daniel
Apr 28 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Apr 28, 2009 at 10:23 PM, Daniel Keep
<daniel.keep.lists gmail.com> wrote:

 That requires f to be a type, which loses you the actual names. =A0And yo=
u
 cannot (last time I checked) have aliases in a tuple.
Check again - tuples can be any arbitrary mix of types, expressions, and aliases. :)
Apr 28 2009
parent reply grauzone <none example.net> writes:
Jarrett Billingsley wrote:
 On Tue, Apr 28, 2009 at 10:23 PM, Daniel Keep
 <daniel.keep.lists gmail.com> wrote:
 
 That requires f to be a type, which loses you the actual names.  And you
 cannot (last time I checked) have aliases in a tuple.
Check again - tuples can be any arbitrary mix of types, expressions, and aliases. :)
Wow, it actually works. But I really don't understand why. It seems the compiler directly passes symbols as tuple arguments, and later dumbs it down to what it needs (like an alias, a type, ...). Makes me think nobody will ever be able to write a separate bug-free DMD frontend. I'm scared.
Apr 29 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 29, 2009 at 3:03 AM, grauzone <none example.net> wrote:

 Wow, it actually works. But I really don't understand why. It seems the
 compiler directly passes symbols as tuple arguments, and later dumbs it down
 to what it needs (like an alias, a type, ...).

 Makes me think nobody will ever be able to write a separate bug-free DMD
 frontend. I'm scared.
Precisely. There is no principle of least surprise in the DMD metaprogramming implementation. There is no consistency. And worst of all, there is no specification.
Apr 29 2009
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Jarrett Billingsley wrote:
 On Wed, Apr 29, 2009 at 3:03 AM, grauzone <none example.net> wrote:
 
 Wow, it actually works. But I really don't understand why. It seems the
 compiler directly passes symbols as tuple arguments, and later dumbs it down
 to what it needs (like an alias, a type, ...).

 Makes me think nobody will ever be able to write a separate bug-free DMD
 frontend. I'm scared.
Precisely. There is no principle of least surprise in the DMD metaprogramming implementation. There is no consistency. And worst of all, there is no specification.
And that tears down the phrase "The lexer, parser and semantic pass don't know each other so that it's easier to implement a compiler for D". Because a D compiler that doesn't use DMD's front-end is not D compatible. Because the front end *is* the specification of the language.
Apr 29 2009
parent grauzone <none example.net> writes:
 D". Because a D compiler that doesn't use DMD's front-end is not D 
 compatible. Because the front end *is* the specification of the language.
...and it's full of bugs.
Apr 29 2009
prev sibling parent reply Georg Wrede <georg.wrede iki.fi> writes:
Jarrett Billingsley wrote:

 Don't you love it?  "Most C++ template features are discovered."  So are D's.
Well, one could say that this is the very definition of a well working metaprogramming system. After all, the whole idea of templates is to let the programmer invent new ways to use the lanaguage, the compiler, and the template system. The worst possible template system is one where everything is by design, and nobody ever discovers anything. One would then ask what the whole point of the template system is.
Apr 28 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 29, 2009 at 2:52 AM, Georg Wrede <georg.wrede iki.fi> wrote:
 Jarrett Billingsley wrote:

 Don't you love it? =A0"Most C++ template features are discovered." =A0So=
are
 D's.
Well, one could say that this is the very definition of a well working metaprogramming system. After all, the whole idea of templates is to let =
the
 programmer invent new ways to use the lanaguage, the compiler, and the
 template system.
That's not.. really at all what the issue is here. The issue is more that most of the metaprogramming features in D are completely unspecified, and when we discover that something works, it's hard to tell if it's _supposed_ to be that way or if we're taking advantage of some weird bug in the compiler. Show me a page that documents .stringof! Thought not. As some other examples, did you know it's possible to get the names of the fields of a struct type (and probably a class type too with a similar method)? It only works under extremely contrived circumstances, using .stringof, and parsing out the names yourself from a very horrible-looking string. It's also possible to get the name of a local variable by instantiating a template in a local scope and parsing a horrid .mangleof string. You can also determine some (not *all*, but some) interesting properties of functions and methods - things like final, static, abstract - by creating dummy inherited classes and attempting to do awful things to them. Metaprogramming should be _well-specified_ and _orthogonal_. I agree with you that the _possibilities_ of metaprogramming should be almost boundless and should allow you to come up with your own DSLs. But the compiler shouldn't hold information about your program "ransom" and make you work so goddamn hard to get at it. I should be able to just write, I don't know, __traits(parameterNames, f) and get a tuple of parameter names! I'm tired of puzzling out information that should be directly available!
Apr 29 2009
parent reply Georg Wrede <georg.wrede iki.fi> writes:
Jarrett Billingsley wrote:
 On Wed, Apr 29, 2009 at 2:52 AM, Georg Wrede <georg.wrede iki.fi> wrote:
 Jarrett Billingsley wrote:

 Don't you love it?  "Most C++ template features are discovered."  So are
 D's.
Well, one could say that this is the very definition of a well working metaprogramming system. After all, the whole idea of templates is to let the programmer invent new ways to use the lanaguage, the compiler, and the template system.
That's not.. really at all what the issue is here. The issue is more that most of the metaprogramming features in D are completely unspecified, and when we discover that something works, it's hard to tell if it's _supposed_ to be that way or if we're taking advantage of some weird bug in the compiler. Show me a page that documents .stringof! Thought not.
Yeah. Just today I posted to Bugzilla asking for an easy way to get the current function name and parameter names. And yes, once you find that you can get some info or get something done with some gymnastics, you can't rely on it being there tomorrow. For all you know, your whole solution may be based on a computer bug that'll get fixed next week.
 As some other examples, did you know it's possible to get the names of
 the fields of a struct type (and probably a class type too with a
 similar method)?  It only works under extremely contrived
 circumstances, using .stringof, and parsing out the names yourself
 from a very horrible-looking string.  It's also possible to get the
 name of a local variable by instantiating a template in a local scope
 and parsing a horrid .mangleof string.  You can also determine some
 (not *all*, but some) interesting properties of functions and methods
 - things like final, static, abstract - by creating dummy inherited
 classes and attempting to do awful things to them.
Sigh. The good thing is, you actually /can/ get the stuff. And it's frustrating. I mean, folks do stumble on these ways of getting the impossible, but the real crappy thing is if you know what you want, it's pretty hard to then come up with the jumps and somersaults needed.
 Metaprogramming should be _well-specified_ and _orthogonal_.  I agree
 with you that the _possibilities_ of metaprogramming should be almost
 boundless and should allow you to come up with your own DSLs.  But the
 compiler shouldn't hold information about your program "ransom" and
 make you work so goddamn hard to get at it.  I should be able to just
 write, I don't know, __traits(parameterNames, f) and get a tuple of
 parameter names!  I'm tired of puzzling out information that should be
 directly available!
Somehow, I can't help believing that will be the case, already before D2 gets out. It's unimaginable that Andrei &co wouldn't have this as the goal. And with their current speed, that day is pretty near! (Ok, ok, in private I do share your frustration. I too do swear att stuff not being documented, others being illogical or plain too hard to use, etc. But I don't know if it serves the end goal if we could have Andrei do more documenting, or whatever. That'd all be time off of the real thing.) ----- In the mean time, maybe we should all start writing on the "best practices" on wiki4d every time we stumble upon a way to get/do something cool/useful. Pasting from there sure is faster than spending three days each time thinkng and asking around....
Apr 29 2009
parent Don <nospam nospam.com> writes:
Georg Wrede wrote:
 Jarrett Billingsley wrote:
 On Wed, Apr 29, 2009 at 2:52 AM, Georg Wrede <georg.wrede iki.fi> wrote:
 Jarrett Billingsley wrote:

 Don't you love it?  "Most C++ template features are discovered."  So 
 are
 D's.
Well, one could say that this is the very definition of a well working metaprogramming system. After all, the whole idea of templates is to let the programmer invent new ways to use the lanaguage, the compiler, and the template system.
That's not.. really at all what the issue is here. The issue is more that most of the metaprogramming features in D are completely unspecified, and when we discover that something works, it's hard to tell if it's _supposed_ to be that way or if we're taking advantage of some weird bug in the compiler. Show me a page that documents .stringof! Thought not.
Yeah. Just today I posted to Bugzilla asking for an easy way to get the current function name and parameter names. And yes, once you find that you can get some info or get something done with some gymnastics, you can't rely on it being there tomorrow. For all you know, your whole solution may be based on a computer bug that'll get fixed next week.
 As some other examples, did you know it's possible to get the names of
 the fields of a struct type (and probably a class type too with a
 similar method)?  It only works under extremely contrived
 circumstances, using .stringof, and parsing out the names yourself
 from a very horrible-looking string.  It's also possible to get the
 name of a local variable by instantiating a template in a local scope
 and parsing a horrid .mangleof string.  You can also determine some
 (not *all*, but some) interesting properties of functions and methods
 - things like final, static, abstract - by creating dummy inherited
 classes and attempting to do awful things to them.
Sigh. The good thing is, you actually /can/ get the stuff. And it's frustrating. I mean, folks do stumble on these ways of getting the impossible, but the real crappy thing is if you know what you want, it's pretty hard to then come up with the jumps and somersaults needed.
 Metaprogramming should be _well-specified_ and _orthogonal_.  I agree
 with you that the _possibilities_ of metaprogramming should be almost
 boundless and should allow you to come up with your own DSLs.  But the
 compiler shouldn't hold information about your program "ransom" and
 make you work so goddamn hard to get at it.  I should be able to just
 write, I don't know, __traits(parameterNames, f) and get a tuple of
 parameter names!  I'm tired of puzzling out information that should be
 directly available!
Somehow, I can't help believing that will be the case, already before D2 gets out. It's unimaginable that Andrei &co wouldn't have this as the goal. And with their current speed, that day is pretty near!
Another factor -- we all have the compilable DMD backend now. With many of these things, we can still make them happen even though Walter's overloaded.
 
 (Ok, ok, in private I do share your frustration. I too do swear att 
 stuff not being documented, others being illogical or plain too hard to 
 use, etc. But I don't know if it serves the end goal if we could have 
 Andrei do more documenting, or whatever. That'd all be time off of the 
 real thing.)
 
 -----
 
 In the mean time, maybe we should all start writing on the "best 
 practices" on wiki4d every time we stumble upon a way to get/do 
 something cool/useful. Pasting from there sure is faster than spending 
 three days each time thinkng and asking around....
Apr 30 2009