Currently given a template symbol it's not possible to do simple introspection on it, such as getting arity, distinguishing alias vs. type parameters, and figuring out variadics.
Example:
template A(alias sym)
{
...
}
A!((a, b) => a.name < b.name);
A is unable to tell the number of parameters of the lambda. It could if it knew what type to instantiate it, and in order to know that it needs the actual instantiation type. There should be enough introspection chops to compute the number of parameters without instantiating the lambda.
There would be a fair amount of design involved because currently there's no kind that expresses a template's parameters outside the template.
Comment #1 by andrej.mitrovich — 2013-02-27T15:16:48Z
Is Issue 4265 relevant in any way (does it help?)?
I think I almost have a pull ready for Issue 4265, but it depends on whether people really want the feature.
Comment #2 by andrej.mitrovich — 2013-03-23T11:32:36Z
(In reply to comment #0)
> There would be a fair amount of design involved because currently there's no
> kind that expresses a template's parameters outside the template.
I don't think we need to design much. We could provide traits. For example:
template A(alias sym)
{
__traits(getArity, sym); // 2 - or paramCount
__traits(isAliasParam, 0, sym); // 0 == index of param
}
A!((a, b) => a.name < b.name);
template B(alias sym)
{
__traits(isValueParam, 0, sym); // true
__traits(isTypeParam, 1, sym); // true
__traits(isVariadicParam, 2, sym); // true
}
void X(int val, Type, Args...)(Args t) { return 0; }
B!(X);
And then you could wrap all of this into a Phobos template which collects all the data. let's call it TemplateInfo:
template B(alias sym)
{
alias ti = TemplateInfo!sym;
static assert(ti.params.count == 2);
static assert(ti.params[0].isValueParam);
}
void X(Type, int val)() { }
B!(X);
That sort of stuff.
Comment #3 by andrei — 2013-03-24T05:34:07Z
Yah, issue 4265 is related. For this one, the challenge is defining a minimal and complete set of traits.
Comment #4 by andrej.mitrovich — 2014-04-28T15:17:43Z
Assigning this to myself. There's a whole host of traits that will be coming.
Comment #5 by andrej.mitrovich — 2014-04-30T12:36:01Z
Would it be possible to get the parameter types of a lambda which has some parameter types specified and some not? In that case I would expect "void" to be returned for those parameters that don't have a specified type.
(int a, b) => a + b
Comment #7 by andrej.mitrovich — 2014-05-10T14:43:00Z
(In reply to Jacob Carlborg from comment #6)
> Would it be possible to get the parameter types of a lambda which has some
> parameter types specified and some not? In that case I would expect "void"
> to be returned for those parameters that don't have a specified type.
>
> (int a, b) => a + b
This probably expands to:
void func(T)(int a, T b);
Therefore it has 1 template parameter. If you use __traits(getTemplateParamCount, lambda) it will return 1.
Comment #8 by doob — 2014-05-10T14:46:07Z
I'm interested to know if std.traits.ParameterTypeTuple (or similar) would work with lambdas with both regular types and templated types.
Comment #9 by andrej.mitrovich — 2014-05-10T14:48:29Z
(In reply to Jacob Carlborg from comment #8)
> I'm interested to know if std.traits.ParameterTypeTuple (or similar) would
> work with lambdas with both regular types and templated types.
Well I'd imagine changing what ParameterTypeTuple does right now would probably break a lot of code. So it's probably best to write a new set of library wrappers for the new traits. It's not very easy to combine all of these different types nto a single template.
Comment #11 by andrej.mitrovich — 2016-05-06T22:24:10Z
Recapping from the PR just closed (temporarily):
-----
Ok, I'll start a discussion in the forums soon with a proposal of a (sub)set of the new traits and see which ones we really need, and whether we could implement as many of these in the library instead of adding additional compiler code. Closing for now. :)
-----
I'll bring this up in the forums soon.
Comment #12 by robert.schadek — 2024-12-13T18:04:20Z