Skip to content

Conversation

Geod24
Copy link
Member

@Geod24 Geod24 commented Nov 10, 2014

I often find myself in the need of writing / copy-pasting this code whenever I have a project where I need to do some meta-programming on functions.
It's basic, does one job, and is way simpler to start with than using an is expression.

I was not sure where to put it though, as we don't have anything similar to std.meta.codegen.

@ntrel
Copy link
Contributor

ntrel commented Nov 10, 2014

@Geod24
Copy link
Member Author

Geod24 commented Nov 10, 2014

Similar, but different.

The following code errors with ParameterTypeTuple:

import std.traits : ParameterTypeTuple;
import core.vararg;

void bar(string val);
void foo(ParameterTypeTuple!bar, ...) { assert(val == "test", "Val is: ["~val~"]."); }
void main() { foo("test"); }
// Error: undefined identifier val

My understanding is that ParameterTypeTuple is for CT reflexion rather than CT declaration (a.k.a metaprogramming): it's relatively rare to declare a function with unnamed parameters.

However, it seems that there is a strange bug going on here. The auto-tester fails with:
core.exception.AssertError@std/typecons.d(5257): 42
Line 5257 is:
void bar2(ParameterTuple!foo2, ...) { assert(val == "42", val); }
And it's only called at line 5260, this way: bar2("42");

Declaring bar as not being variadic makes it work. Considering the auto-tester doesn't fail on every platform, I assume it's a compiler bug.

@mihails-strasuns
Copy link

Once compiler bug is taken care of it can make sense to implement ParameterTypeTuple and ParameterNameTuple as thin wrappers on top of this one.

@Geod24
Copy link
Member Author

Geod24 commented Nov 23, 2014

@Geod24 Geod24 force-pushed the add-parametertuple branch 3 times, most recently from 45edffc to 5cfe7c9 Compare December 15, 2014 17:48
@Geod24
Copy link
Member Author

Geod24 commented Dec 15, 2014

I removed the variadic argument, added a mention of the bug, and rebased. Not the best solution, but better than letting this rot.

@@ -5875,3 +5875,93 @@ public:
auto value = cast(int)flags_A;
assert(value == Enum.A);
}
/**
* Returns a Tuple of the parameters.
* It can be used to declare function.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Params: block, no Returns: block.

@Geod24 Geod24 force-pushed the add-parametertuple branch from 5cfe7c9 to 91059f6 Compare January 6, 2015 18:58
@Geod24
Copy link
Member Author

Geod24 commented Jan 6, 2015

@WalterBright : Thanks, I updated the documentation.

@Geod24 Geod24 force-pushed the add-parametertuple branch from 91059f6 to 5cfe7c9 Compare January 12, 2015 20:18
@Geod24
Copy link
Member Author

Geod24 commented Jan 17, 2015

Any additional concern ?

@Geod24
Copy link
Member Author

Geod24 commented Jan 23, 2015

Ping @Dicebot : Is it good to go ?

@mihails-strasuns
Copy link

LGTM, but there is a good chance we can merge #2687 - would be better to merge this after in that case, with ParameterList name.

@Geod24
Copy link
Member Author

Geod24 commented Jan 23, 2015

Missed this one. Good news indeed !
I surely will wait until it gets merged, and update accordingly.

@Geod24
Copy link
Member Author

Geod24 commented Mar 30, 2015

Rebased & fixed in the light of https://issues.dlang.org/show_bug.cgi?id=14369 .
@JakobOvrum : This is a small utility that's easily added to std.meta. Could we go forward with this ?

* Returns a Tuple of the parameters.
* It can be used to declare function.
*/
template ParameterTuple(alias Func)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Func/func/

@JakobOvrum
Copy link
Contributor

So this template exposes __parameters completely bare, complete with its arcane, undocumented details...

This definitely needs better documentation. In the current state of the PR, the only way for a user to use this is to emulate the examples.

@quickfur
Copy link
Member

I don't like exposing __parameters in this way, because it behaves in a very counterintuitive way compared to how the language handles other typetuples (or meta.list, whatever you call them).

For example, tuple indexing notation does not do what you think it does: it extracts the type of the indexed parameter, and discards all other info like name, default argument, etc.. The correct way of "indexing" a parameter type tuple is to take a 1-element slice.

A lot of this unusual behaviour stems from the way it's implemented in DMD. I don't think it's a good idea to calcify DMD's implementation method in Phobos like this. I would rather we encapsulate parameter type tuples inside an opaque type / template that is abstracted from the nitty details of the implementation. Something that provides an abstract interface for indexing parameter type tuples, extracting parameter names, qualifiers, etc..

A lot of this is already provided by Phobos, the only thing is that they may have a less than ideal interface. Still, I would rather improve the user-facing APIs instead of baring implementation details like this, especially __parameters which is one of the strangest parts of the DMD implementation that IMO users shouldn't need to deal with directly.

Not to mention, if this gets into Phobos, documented or not, it becomes a burden upon other D compiler implementors to expose the same counterintuitive, hackish, inconsistent parameter type tuple API, even if their implementations of D allows much cleaner interfaces.

@Geod24 Geod24 force-pushed the add-parametertuple branch from 5e8cb2d to 40b4590 Compare March 30, 2015 23:35
@Geod24
Copy link
Member Author

Geod24 commented Mar 30, 2015

This definitely needs better documentation. In the current state of the PR, the only way for a user to use this is to emulate the examples.

That's the point. You have a list of parameters you can use to declare function. You don't want, and you should not use this list for something else, unless you know the arcanes of is(). The use case is limited to what's described in the examples.

For example, tuple indexing notation does not do what you think it does: it extracts the type of the indexed parameter, and discards all other info like name, default argument, etc.. The correct way of "indexing" a parameter type tuple is to take a 1-element slice.

It does exactly what I think it does. See line 6293. But we agree it doesn't do what you would expect at first sight.

A lot of this is already provided by Phobos, the only thing is that they may have a less than ideal interface. Still, I would rather improve the user-facing APIs instead of baring implementation details like this, especially __parameters which is one of the strangest parts of the DMD implementation that IMO users shouldn't need to deal with directly.

Not to mention, if this gets into Phobos, documented or not, it becomes a burden upon other D compiler implementors to expose the same counterintuitive, hackish, inconsistent parameter type tuple API, even if their implementations of D allows much cleaner interfaces.

We agree on is() oddness. The goal of this P.R. is to make it more obvious, and less arcane, by providing examples of what it can be used for in the real world.
Since this is part of the frontend, it's a NOOP. Another solution, the ideal one, would be to fix DMD. I guess I would go along the lines of exposing a TypeTuple / meta.list of templates that have 3 fields, as described in 14369. But my knowledge of the compiler currently too limited for that task.

@Geod24
Copy link
Member Author

Geod24 commented May 19, 2015

With the recent changes, this doesn't have any value anymore.

@Geod24 Geod24 closed this May 19, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants