Re: What does __parameters return?

2013-09-13 Thread simendsjo
On Thursday, 12 September 2013 at 21:33:48 UTC, Andrej Mitrovic 
wrote:

On 9/12/13, simendsjo simend...@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.


Re: What does __parameters return?

2013-09-13 Thread Jacob Carlborg

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


Re: What does __parameters return?

2013-09-13 Thread simendsjo
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..


Re: What does __parameters return?

2013-09-12 Thread H. S. Teoh
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.


Re: What does __parameters return?

2013-09-12 Thread simendsjo

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 :)


Re: What does __parameters return?

2013-09-12 Thread Andrej Mitrovic
On 9/12/13, simendsjo simend...@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?


Re: What does __parameters return?

2013-09-12 Thread H. S. Teoh
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