Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add draft of variadic notes #76

Merged
merged 5 commits into from
Nov 16, 2021

Conversation

CraftSpider
Copy link
Contributor

I'm interested in the addition of variadics to Rust, and figured I'd start a draft of the design notes mentioned in the closing of rust-lang/rfcs#2775. I'm open to any proposed changes, I figured I'd try to get the ball rolling by putting something down.

src/design_notes/variadic_design.txt Outdated Show resolved Hide resolved
src/design_notes/variadic_design.txt Outdated Show resolved Hide resolved
@PoignardAzur
Copy link

Oh hey, I completely missed that!

Anyway, I wrote a summary/analysis of variadic proposals last week.

It's not quite as formal as what you're trying to do, but hopefully it can help.

@nikomatsakis
Copy link
Contributor

@CraftSpider thanks for doing this!

@clarfonthey
Copy link

clarfonthey commented Mar 4, 2021

Hey, I was looking through stuff figuring out where we were with respect to variadic generics and found this. Was wondering what the status of this is and/or if it would make sense to have an open issue in this repo on what the status of variadic generics are. Figure it's not nearly the same level of priority as const generics, but potentially still useful to have.

Side note one thing that is probably worth considering also is that variadic generics should not only support variadic types, but variadic constants too. For example, for something like the ndarray crate simply having const generics isn't enough and you need variadic generics to also support multiple dimensions.

@CraftSpider
Copy link
Contributor Author

I'm not sure what the current status of this PR is, I think it needs at least another @jplatte review/approval. As for ideas related to variadic const generics, I'd be willing to add notes on that, or that could be delayed till after this merges then open another PR for that. I slightly prefer the second, in the name of getting MVP out there, but if others prefer the first option I'll work on updating it.

@jplatte
Copy link

jplatte commented Mar 9, 2021

This definitely does not need approval from me, I'm simply a community member and not on the lang team 😄

@CraftSpider
Copy link
Contributor Author

Oh, I'm very sorry for pinging you then :P
I'm not sure who I should look to for approval, I'll likely ask in the Rust zulip or such

@clarfonthey
Copy link

I should add that I'm mostly just mentioning variadic const generics as a note that it probably should be figured out at some point, although I don't think you should have to do much extra to get this merged. The note here in the PR is good enough for me :)

@joshtriplett
Copy link
Member

Can I suggest renaming the filename to specifically mention "variadic generics", since there are other meanings for "variadics" in the context of Rust (e.g. C-style varargs)?

@CraftSpider
Copy link
Contributor Author

Done

be seen as just a tuple with N elements. The syntax is thus built around allowing expansions of tuple
types into their components, and taking multiple types that will be condensed into a tuple.

For using these types, it is proposed that one destructure the tuple, generally into a single head, and the remaining
Copy link
Member

Choose a reason for hiding this comment

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

@eddyb also has previously expressed a preference for symmetric VG-- that is, VG, which would allow pulling out the first or last element, rather than fixing the choice of left->right traversal or right->left traversal. I don't know how important I personally feel this is, but it's worth noting given that this was the subject of quite a bit of discussion in previous proposals.

- Mentioned by eddyb, a subtuple type could have different padding than its parent.
EG: `&(A, B, C, D) != &A, &(B, C, D)`

- The `..` syntax is already used in ranges, so some other syntax would be needed
Copy link
Member

Choose a reason for hiding this comment

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

We have ...T syntax (three dots) available now, since inclusive ranges now use ..=.


### Cons

- Overlaps with inclusive range syntax, though it shouldn't actually break any backwards compatibility
Copy link
Member

Choose a reason for hiding this comment

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

inclusive range syntax now uses ..=

@cramertj
Copy link
Member

cramertj commented Jun 8, 2021

One topic that I don't see mentioned here is tuple layout. This was the subject of a lot of discussion previously. Currently, it's not required that the "tail" of a tuple be represented contiguously. That is, if we were to allow something like &(A, B, C) -> &(B, C), we'd need it to be the case that (A, B, C) contains a subtuple representation of (B, C). Today, this is not necessarily the case, as (A, B, C) may be organized like (C, A, B) (etc.) in memory. This is the reason my previous proposal was to offer "magic" tuple methods via a Tuple trait to go from (A, B, C) to (&A, &B, &C), which could then form the basis for the implementations.

My current position has changed, actually-- after talking with @sgrif and others, I became fairly convinced that it would be fine to take a slight hit in terms of tuple representation efficiency and left-right symmetry in order to get more ergonomic and smaller code-sized tuple trait implementations. Rather than allowing arbitrary reordering of tuple fields, we could force earlier fields to be placed "outside" later fields. That is, we need (A, B, C) to contain (B, C), so we can't allow (C, A, B), but we can allow (A, B, C) or (B, C, A). We can consider alignment requirements and efficiency when deciding whether to place each element at the front or the back of a tuple, but we cannot insert it inside the tail. This would unlock things like this:

impl Visit for () {
    fn visit(&self) {}
}
impl<H: Visit, T: Tuple + Visit> Visit for (H, ...T) { // `...T` syntax splats a tuple type into a variadic generic arg
    fn visit(&self) {
        self.0.visit();
        self[1..].visit(); // Tuples now implement `Index` with `RangeFrom` support (but not `RangeTo`)
    }
}

@crlf0710
Copy link
Member

crlf0710 commented Jul 22, 2021

I'd love to see some proposal on supporting "concatenating" arbitrary tuples together, and their corresponding type-level calculation. I feel such impls are hard to write today even using compiler magic. I hope variadic design could address this issue.

@Mark-Simulacrum
Copy link
Member

Pushed up some changes per your feedback, @cramertj.

@nikomatsakis nikomatsakis merged commit cf6dab4 into rust-lang:master Nov 16, 2021
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.

9 participants