Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: variadic generics #10124
Comments
This comment has been minimized.
This comment has been minimized.
|
Have you tried implementing the same use cases using macros? If so, how well did it work? |
This comment has been minimized.
This comment has been minimized.
|
Well, I'm not sure if any of this can be implemented with macros. You can emulate some variadic functions with macros (by writing them as macros in the first place), but it's nowhere near automatic. |
This comment has been minimized.
This comment has been minimized.
|
My feeling: I think we will eventually want something like this if we aim to have trait types subsume closure types, but not for 1.0. I liked the idea of leveraging tuples but I don't know if complications arise and so forth. |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis afaik @eddyb is actively working on impleementing this |
This comment has been minimized.
This comment has been minimized.
|
(also, |
This comment has been minimized.
This comment has been minimized.
|
I've done some research for the first part, expanding |
This comment has been minimized.
This comment has been minimized.
|
@catamorphism The issue with macros is: a. they cannot be used in methods, b. they are brittle and don't give very good error messages, and c. they have no knowledge of the type system. The nice thing about variadic generics is also that it will allow us to desugar lots of the language. @eddyb Have you looked at D's variadic type params? |
This comment has been minimized.
This comment has been minimized.
|
@eddyb: maybe another implementation to look at would be clay, though they have a quite a bit more powerful generics system than Rust. |
This comment has been minimized.
This comment has been minimized.
|
@bjz I have now, it uses tuples as well, but I'm not seeing tuple destructuring (e.g. @Blei oh, Clay has pretty much the same concept, AFAICT. Thanks for that, better to reinvent the wheel in a way that works (and we like prior work in Rust, don't we?). |
This comment has been minimized.
This comment has been minimized.
|
@eddyb Why not T.. ? (A,B,C).. => A,B,C fn call(self, args: Args..) -> Ret { |
eddyb
referenced this issue
Dec 2, 2013
Closed
Allow expanding a tuple type `T` in a list of types with `..T`. #10769
This comment has been minimized.
This comment has been minimized.
|
@liigo prefix That being said, I'm not fundamentally opposed to a postfix |
This comment has been minimized.
This comment has been minimized.
|
My only concern here is whether/how this might interact with type inference, and future things like higher-kinded types (or i.o.w. just the presence of a kind level above the type level at all), type-level currying if we ever add it (see "Type system thoughts" email for why we might want to), and so forth. In particular, if we have kinds, would And, there's some of this in the OP, but could you do a compare-and-contrast (of advantages/disadvantages, expressiveness, simplicity/complexity etc.) relative to C++'s variadic templates? Variadic templates are super useful, but they're also super far away from anything that could be called simple and elegant. |
This comment has been minimized.
This comment has been minimized.
|
I'll admit to some trepidation about potential interactions with other parts of the type system as well. I don't know what problems might arise because I haven't given this any serious thought, and I don't think I will have time to give this serious thought until the rest of the system is more nailed down. |
This comment has been minimized.
This comment has been minimized.
|
I read over the proposal in more detail and I've got some thoughts and questions. First off, I think we may want to model this in the Rust model that I've been working on. This is, after all, what it's for -- to uncover complications that arise before we are knee deep in implementation. Unfortunately the model is currently limited to the reduction semantics (no type system yet). Second, here is an attempt to codify the rules that I see in what you wrote. Let me know if you think this is accurate:
I think this largely holds together, but this is only a cursory examination. Mostly just trying to extract rules from the examples. I didn't think too hard about HKT, but my first thought is that a tuply type parameter just has kind Some questions / thoughts
But by the rules I gave above this an error, because
|
This comment has been minimized.
This comment has been minimized.
|
Ah, I see in your examples you permit a "tuply" type parameter to come first in the list as well. I think we'll need a rule like "at most one tuply type parameter on any given type" to prevent ambiguity. I could imagine this creating problems, though. Another option might be that we require users to provide tuple types for the values of tuply type parameters -- or maybe permit either In other words, given |
This comment has been minimized.
This comment has been minimized.
|
Thinking more about this, I see that my attempt at crafting rules was wrong. The type grammar is more like:
and so on. |
This comment has been minimized.
This comment has been minimized.
|
@eddyb wrote to me on IRC that I was misinterpreting the meaning of |
This comment has been minimized.
This comment has been minimized.
C++11 allows template parameter packs out of anything, including templates (higher kinds) and non-types, which in this case we wouldn't. The primary incentive to have them at all though is function parameter lists, which are simply-kinded, so maybe this is not a problem. |
This comment has been minimized.
This comment has been minimized.
|
cc |
pnkfelix
referenced this issue
Feb 18, 2014
Closed
implement Hash on tuples and owned containers #5195
eddyb
referenced this issue
Mar 12, 2014
Closed
Add multi-element wildcards to tuples and tuple-structs #10365
This comment has been minimized.
This comment has been minimized.
|
@eddyb this proposal's got quite a feedback. All RFCs should now go through the new RFC process but it will take time to write all those RFCs. However, given the feedback on this proposal, it would be good to submit it in the rfc repo and start getting some feedback there as well. |
This comment has been minimized.
This comment has been minimized.
|
Just thought I'd |
japaric
referenced this issue
Jul 21, 2014
Closed
Expand macro section on repetition operators and syntax. #185
This comment has been minimized.
This comment has been minimized.
|
Should this be rewritten and go through the new RFC process? |
This comment has been minimized.
This comment has been minimized.
|
@sinistersnare: Yes, that's what needs to happen to it. It's not a backwards incompatibility risk so there's no point in leaving around an issue here. |
thestinger
closed this
Sep 16, 2014
This comment has been minimized.
This comment has been minimized.
|
This issue has been moved to the RFCs repo: rust-lang/rfcs#376 |
eddyb commentedOct 28, 2013
The Problem
bindmethod,f.bind(a, b)(c) == f(a, b, c)) and defining such functions may only be done (in a limited fashion) with macrosThe Solution: Part One
C++11 sets a decent precedent, with its variadic templates, which can be used to define type-safe variadic functions, among other things.
I propose a similar syntax, a trailing
..Tin generic formal type parameters:The simple example above only uses
..T, but notTitself.The question which arises is this: what is
T? C++11 has a special case for variadic parameter packs, but we can do better.We have tuples. We can use them to store the actual variadic generic type parameters:
The Solution: Part Two
Now that we know the answer is "tuples", everything else is about extending them.
The prefix
..operator would expand a tuple type:Then we can do the same thing with values:
There's only one piece missing: we're still not able to define a function which takes a variable number of arguments.
For this, I propose
..x: T(where T is a tuple type) in a pattern, which can be used to "capture" multiple arguments when used in fn formal arguments:A type bound for
..T(i.e.impl<..T: Trait>) could mean that the tupleThas to satisfy the bound (or each type inT, but that's generally less useful).Examples:
Todo