www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What does __parameters return?

reply "simendsjo" <simendsjo gmail.com> writes:
The documentation says "the parameter tuple of a function, 
delegate, or function pointer. This includes the parameter types, 
names, and default values."

.. but what type is it?

Error: argument (int i, char c, string s, bool b = false) to 
typeof is not an expression

How am I supposed to get the parameter names using this?

It's possible to use .stringof, and then regular string handling 
to extract the names, but I guess there should be a simpler way 
if only I knew what it returned.
Sep 12 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 12, 2013 at 08:44:29PM +0200, simendsjo wrote:
 The documentation says "the parameter tuple of a function, delegate,
 or function pointer. This includes the parameter types, names, and
 default values."
 
 .. but what type is it?
 
 Error: argument (int i, char c, string s, bool b = false) to typeof
 is not an expression
 
 How am I supposed to get the parameter names using this?
 
 It's possible to use .stringof, and then regular string handling to
 extract the names, but I guess there should be a simpler way if only
 I knew what it returned.
You're not going to like the answer to this one... :) Here's some example code that uses __parameters to inspect a function and print out a list of its parameter types and names (my explanations are in the comments): -------------snip------------- import std.stdio; // Example function we want to examine parameters for int func(string x, float y, int z=123) { return 0; } void main() { // __parameters appears to only work inside is(...), in a quirky // special-cased syntax that ONLY works when written exactly in the // form is(TypeOfFunc Ident == __parameters), in which case Ident gets // aliased to a "parameter tuple", an elusive compiler internal entity // that is similar to, but not the same as, a "type tuple". static if (is(typeof(func) Params == __parameters)) { // You already know what does one this, I believe. pragma(msg, Params.stringof); // foreach works on parameter tuples, but it acts very weird. // If a single argument is given, it gets assigned to the // *type* of the parameter in question. If two arguments are // given, like here, the first is assigned the index into the // parameter tuple, and the second to the *type* of the // corresponding parameter. foreach (i, T; Params) { // This quirky behaviour of foreach on parameter tuples // means T is *not* the parameter itself, merely the // *type* of the parameter. To get the actual // parameter's description, we need a 1-element slice // of the parameter tuple. Thankfully, i has been // conveniently assigned the index of the current // parameter, so we can use that for the slicing: alias Param = Params[i .. i+1]; // As I said, T is merely the type of the parameter, // not the parameter itself. alias ParamType = T; // The 1-element slice Param behaves as if it's an // independent entity with a name, so we can use // __traits(identifer, ...) to get at the parameter // name. string ParamName = __traits(identifier, Param); writeln("type=", T.stringof, " name=", ParamName); // Not shown here is the default parameter value. // Looking at std.traits.ParameterDefaultValueTuple, // there appears to be no direct way to get at this. // The only way seems to be to declare a function with // Param as its single argument, and then call that // function with no arguments so that the function can // return the default value of the parameter. This is // what Phobos actually does to build the default // parameter tuple. // Also not shown here is how to get at the // storage class of the parameter; I didn't look // into this, but your best reference would be // std.traits.ParameterStorageClass' code. } } } -------------snip------------- Given the non-intuitive quirkiness of the whole thing, you're probably far better off using Phobos' std.traits.Parameter...Tuple templates to get at the various bits of function parameters. Or just parse the string returned by the .stringof value, as you suggested. T -- Never wrestle a pig. You both get covered in mud, and the pig likes it.
Sep 12 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Thursday, 12 September 2013 at 19:41:26 UTC, H. S. Teoh wrote:
 On Thu, Sep 12, 2013 at 08:44:29PM +0200, simendsjo wrote:
(...)
 .. but what type is it?
 
 Error: argument (int i, char c, string s, bool b = false) to 
 typeof
 is not an expression
 
 How am I supposed to get the parameter names using this?
 
(...)
 You're not going to like the answer to this one... :)
(...)
 Or just parse the string returned by the .stringof value, as you
 suggested.
Thanks. I just ended up using both is(__parameters and is(function to fetch the parameter names. Sometimes it seems things are added to D without a very thorough design phase, but then again, it starts with "__", so I guess I'm on my own :)
Sep 12 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 12, 2013 at 10:40:06PM +0200, simendsjo wrote:
 On Thursday, 12 September 2013 at 19:41:26 UTC, H. S. Teoh wrote:
On Thu, Sep 12, 2013 at 08:44:29PM +0200, simendsjo wrote:
(...)
.. but what type is it?

Error: argument (int i, char c, string s, bool b = false) to typeof
is not an expression

How am I supposed to get the parameter names using this?
(...)
You're not going to like the answer to this one... :)
(...)
Or just parse the string returned by the .stringof value, as you
suggested.
Thanks. I just ended up using both is(__parameters and is(function to fetch the parameter names. Sometimes it seems things are added to D without a very thorough design phase, but then again, it starts with "__", so I guess I'm on my own :)
I think Walter's official statement on the matter is that __traits is not intended to be used by user code, but to allow Phobos to access compiler internals so that it can provide more user-friendly wrappers around the raw functionality. T -- Nobody is perfect. I am Nobody. -- pepoluan, GKC forum
Sep 12 2013
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/12/13, simendsjo <simendsjo gmail.com> wrote:
 Thanks. I just ended up using both is(__parameters and
 is(function to fetch the parameter names. Sometimes it seems
 things are added to D without a very thorough design phase, but
 then again, it starts with "__", so I guess I'm on my own :)
Have you tried using ParameterIdentifierTuple from std.traits?
Sep 12 2013
parent reply "simendsjo" <simendsjo gmail.com> writes:
On Thursday, 12 September 2013 at 21:33:48 UTC, Andrej Mitrovic 
wrote:
 On 9/12/13, simendsjo <simendsjo gmail.com> wrote:
 Thanks. I just ended up using both is(__parameters and
 is(function to fetch the parameter names. Sometimes it seems
 things are added to D without a very thorough design phase, but
 then again, it starts with "__", so I guess I'm on my own :)
Have you tried using ParameterIdentifierTuple from std.traits?
The problem with this is that you need to supply the symbol. If you are located inside an overloaded function, you will get the first function defined when using the function name. This means you'll have to look at the parent, get overloads, and then find the correct overload (the one you're currently in) by doing some __parameters hacking. And if you're in a templated function, it looks even worse. Seems I cannot get the "overloads" of a template. So my solution is to use a mixin template.. The template itself defines a dummy variable (so you don't have to pass a symbol), use __traits(parent), and then use __parameters and __traits(function) to find the names. Of course, calling ParameterIdentifierTuple!(__traits(parent ... in the mixin template simplifies the implementation quite a bit. Didn't know you could call __traits(identifier for the __parameter values. __parameters is practically undocumented, and doesn't even have an example.
Sep 12 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-09-13 08:33, simendsjo wrote:

 Didn't know you could call __traits(identifier for the __parameter
 values. __parameters is practically undocumented, and doesn't even have
 an example.
It's documented here: http://dlang.org/expression.html#IsExpression Scroll down to the table, next to format 6. Sure, it's not documented much, but at least it's mentioned. -- /Jacob Carlborg
Sep 13 2013
parent "simendsjo" <simendsjo gmail.com> writes:
On Friday, 13 September 2013 at 07:42:48 UTC, Jacob Carlborg 
wrote:
 On 2013-09-13 08:33, simendsjo wrote:

 Didn't know you could call __traits(identifier for the 
 __parameter
 values. __parameters is practically undocumented, and doesn't 
 even have
 an example.
It's documented here: http://dlang.org/expression.html#IsExpression Scroll down to the table, next to format 6. Sure, it's not documented much, but at least it's mentioned.
Yeah, I copied the documentation in my first post - a single line: "the parameter tuple of a function, delegate, or function pointer. This includes the parameter types, names, and default values." But it's quite strange..
Sep 13 2013