-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Raw Keywords #3098
base: master
Are you sure you want to change the base?
Raw Keywords #3098
Conversation
Only the 2021 change is time-critical -- anything using already-reserved syntax space can be decided upon later.
@danielhenrymantilla I think the answer there is that it fails to tokenize, like happens with |
Nice 🙂 could you still mention that lexing requirement somewhere in the RFC? |
@rfcbot fcp merge Per the @rust-lang/lang team meeting today, this has been discussed for some time on Zulip and we have general consensus that we like this feature and would like to see it go through (though there are a few points of active discussion). This is somewhat time sensitive because we are trying to finalize the list of "edition candidate changes" and this would be on the list. Therefore, I'm going to fcp merge. |
Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
For my part: I think this helps address a crucial "tension" around editions -- I would like editions to come every few years, because I think more than that and it will be overwhelming, but I also want us to keep the train model working and having new features land. I've also toyed with ideas like the ones that Ember has proposed, where you expose (and stabilize) "core building blocks" that let people build features in user-space before you stabilize the final user-facing form of the feature. I think that's awesome too, but I've found that for many of the features and RFCs I've looked at, its not obvious how to apply it. The (Thinking more about it, I realize these are two distinct things: the goal of the Ember form is to open up the design space for exploration by end-users, precisely for those cases where the final shape is not known; that's not really addressed by this RFC per se.) |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
I would very much like to see the 2015/2018 edition question settled in the RFC itself, rather than deferred to a "we could". I strongly suspect that "we could" will end up becoming "we didn't". I'd like the RFC to actually commit to addressing this, rather than deferring it to future work. |
@scottmcm Thank you, I really appreciate it. And I agree entirely with the principle you stated: "It's better for raw keywords to be nice on 2021 than for them to be consistent with 2015". |
i'm firmly on -1 side if you're going to introduce both the purpose of this RFC is to "reserve a (non-contextual) keyword" until the next edition comes, so why do we care so much about the aesthetics of a temporary syntax? it is especially silly to introduce two different syntaxes in pre-2018 ( imo you either
|
Hmm. @kennytm I'm not sure if this is exactly what you were proposing, but I have to admit that using do async fn foo() {
} ..reads nicely compared to... k#async fn foo() {
} The major problem I see there is that it's not a single token. I suspect this will have implications. It'd be a pain to integrate into the parser. |
FWIW, I think the motivation and rationale here is strong, but I'm not at all tied to the specific form proposed. It's picked basically as the simplest thing that's evocative of raw idents, but I'd be happy to switch to a better lexical or syntactic form if one is found. (And this could include things like a new keyword in the edition as the normal way to do this.) I'm not a big fan of |
FYI Java does have introduced hyphenated keywords, e.g. public non-sealed class WeirdShape extends Shape { ... }
// ^~~~~~~~~~ |
@nikomatsakis my preference, in order
|
|
Er, wait, it probably has the same macro problems. |
If crater tells us we can do I don't think anything along the lines of |
I would like to propose one last addendum to this RFC: eliminate all currently-reserved-but-unused keywords. Currently (stable) Rust reserves but does not use the following keywords:
Since the mechanism introduced in this RFC is intended to obviate the need for such speculatively-reserved keywords, it seems reasonable to dogfood the feature by un-reserving these keywords. (Of course, some of these keywords are in implemented-but-unstable features, e.g. |
(It occurs to me that one reason to support this feature on earlier editions is, ironically, macros: if we accept my prior comment then the definition of |
I've given this some thought and I think I've come back to preferring My reasoning, roughly in order of importance to me:
|
I've filed RFC 3101 for syntactically reserving |
I don't think this feature sounds very useful for its stated purpose. I wouldn't describe this syntax as "slightly less nice" than actually having these reserved as keywords; I would describe it as substantially worse. If I were driving a feature that requires new keywords (like async/await), I would be strongly against stabilizing that feature before the most recent edition has those keywords as fully reserved. Or I would be if this feature were the only alternative; I would be searching for some alternative syntax we could use instead of keywords if I really wanted to ship before that edition. So if async/await had not been reserved in 2018, I would have found it unacceptably user-unfriendly to expect everyone to write I don't think the 3 year cadence is actually very problematic. async/await was the major feature we shipped the fastest. Let's say I had picked it up a year later, in December 2018, instead of December 2017 (so right after the 2018 edition shipped). This is assuming that the feature's prehistory with Alex's version hadn't given us cause to reserve the keywords. Even then, it would not have been considered ready to ship until fall 2020 in this timeline. So in that hypothetical world, we'd be talking about delaying the feature less than a year; probably we'd be trying to push edition 2021 forward a few releases in the worst case to cut down the delay. So to summarize: I have a hard time imagining that the Rust project would ever actually use this feature. I also think this has a real downside. Even if its never used, it'll end up as yet another weird token types to be enumerated in the back of some reference manual, the sort of thing that reminds me of the non-design I see in programming languages that evokes for me the manuals for my kitchen appliances. This seems to be pushed really fast to meet the edition cut off for the tokenization changes. I'd encourage just doing #3101 for that purpose instead and letting this get more rounds of internal and external feedback instead of pushing this through in a week. |
With the syntax reserved, this doesn't actually need to be implemented until there's a keyword to be added, unless we want to ensure that previous editions can use async/await. |
to avoid the issue with pub 'async' fn my_fn() -> i32 {
calculate().'await'
} |
I like the idea in general, but would want to bikeshed a bit about the syntax... I would prefer k#keyword on all editions, if it passes crater, or else r#$keyword on all editions. Having different syntaxes on different editions completely defeats the secondary purpose of simplifying the mental model of the parser: With this in place, the parser only care about editions when deciding whether to parse an unprefixed identifier as a keywords instead of an identifier. (Obviously there are other differences between editions, primarily in selecting prelude and determining lint levels (including making some lints a hard error on some editions but not other), but those shouldn't affect the parser.) |
|
||
Python uses [*future statements*](https://docs.python.org/3/reference/simple_stmts.html#future) to allow use of the new features on a per-module basis before those feature become standard. Rust's `#![feature(foo)]` on nightly is similar here. | ||
|
||
Haskell has the [`LANGUAGE` pragma](https://ghc.readthedocs.io/en/8.0.2/glasgow_exts.html#language-pragma), which `ghc` also supports as command line parameters. This is again similar to Rust's `#![feature(foo)]` on nightly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind saying more why using #![feature]
to enable new keywords (on nightly or stable) isn't possible or desirable? I believe that the parser in rustc currently does not know about features, but I do not see why it couldn't (except maybe complexity with macros).
|
||
This RFC is thus a proposal to add that general mechanism. | ||
|
||
The other thing that was learned with the 2018 edition is that the period between editions is long enough that the normal "stability without stagnation" principle of "it can just wait for the next train" doesn't work. Instead, it encouraged rushing to try to get things in on time, which had negative quality of life consequences for many contributors. As such, it's important that an alternative mechanism be made available so that missing an edition train doesn't mean having to wait another 3 years -- even if that alternative has syntax that's slightly less nice until the next train. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like the word "slightly" here is a subjective assertion that does not match my view. Something like k#catch { ... }
looks quite poor to me, and I think will make documentation and teaching more difficult. The k#
prefix doesn't just go away during the next edition, it is around forever. I can imagine trying to explain these things to novice users could increase the load when trying to learn a language that is already quite syntax-heavy. It is also a small burden on tooling.
This also pre-supposes a 3-year cadence for editions, which is not mandated in #3085. My impression is that features that add new keywords usually take years to develop (in the design, RFC, implementation, testing, stabilization, documentation steps). I would think that if something of that magnitude is ready in say 2023, a new edition release could be coordinated to ship it that year to avoid making the feature wait until 2024.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
k#
prefix doesn't just go away during the next edition, it is around forever.
I'm not sure I follow that; for any given keyword, k#
does go away during the next edition.
We discussed this RFC again in the lang team triage meeting today. For the short-term goal of the reservation for the edition, we'll be moving forward on #3101 instead. As such, we wanted to leave more time for conversations about this one, and maybe use crater results from 3101 to make design changes, @rfcbot cancel |
@scottmcm proposal cancelled. |
Regarding these two points...
It's not desirable, in my view, because it creates a situation where the set of keywords you can use in a program is not determined solely by the current edition, but also by the feature flags present on the crate. This means we wind up with a kind of 'combinatorics' of Rust dialects. It's also true that the recognizing keywords is typically done at the lexer level, so there is a bit of a feedback issue between These are the reasons that we opted to use
The objective here, ultimately, is to disconnect the stabilization and progress of features from the edition schedule, in an effort to avoid developer stress. It's true that we could potentially have (e.g.) yearly edition, but that has non-trivial costs -- both in terms of public perception, but also in terms of developer stress brought on by having more regular deadlines. Putting together an edition is some amount of planning effort, even a relatively low-key one like Rust 2021. |
Thank you for responding. For me, it helps to explicitly write down reasons why alternatives are not chosen so that they don't remain as tribal knowledge. For example, I had a sense there is a discomfort with the way Haskell language extensions work, but I have not seen the reasons written down. But perhaps I should have been clearer. From my perspective (as a user), there is already a combinatorics of syntax on nightly with the My intent was to say, allow new keywords to be enabled with I think some of the stress for editions is caused by the lack of treating it as a train. Although #3085 tries to frame it as a train release, in practice 2021 has not been that. It has been a rush to see what changes can be squeezed in, even if that means missing deadlines. Obviously that is due to the large difference in timeframes from regular Rust releases (and this being a volunteer process, ❤️s to everyone working on it). But I don't think it is fair to frame an edition as a train-style release vehicle when there is no prescribed schedule and things people really want are allowed to push deadlines. If the intent is to relieve stress, it may be worth examining the edition process more closely, as the rush will still happen for non-keyword changes. |
Yes! I really like to have a thorough explanation of the alternatives and the rationale around them. I thought that much of what I said was in alternatives section of the 2021 RFC, but I guess that's not entirely true.
This is already possible; I don't think we need an RFC for this. The point here is to permit stabilization, not nightly experimentation. I guess the key question is precisely whether it's good to put back-pressure on potential new keywords that may be ready long before the edition release. I think we have plenty of checks that come before we get to the point of stabilization and I'm not overly concerned about things being stabilized willy-nilly. To me, the strongest argument against this proposal is that it's incomplete; only some kinds of new features (those reliant on keywords) can be phased in this way. Things like RFC 2229 would not be applicable, unless we added an artificial keyword to use for opt-in. I'm not sure whether that's a problem or not, we'll have to see in time. I do still think of Editions as trains, even if they are trains on an irregular schedule; I also agree that we've not been strict about the deadlines, but we've also tried to treat them meaningfully. We ruled out a number of things that didn't seem to be approaching consensus. We allowed the 'reserve syntactic space' to stay on the list because the team seemed to be in favor of the general idea and the remaining concerns seemed fairly narrow, almost like implementation details. However, we did agree in the last meeting that those really ought to be ironed out by the next meeting (minutes are here, though I don't think we've well publicized this). |
With #3101 shipped today, and nothing really happening here, I'm going to close this for now -- we can always reopen later. |
This came up a couple of times, and several folks (myself, @nikomatsakis, and @pnkfelix) were all surprised to realize we'd never ratified it, let alone implemented it. This keeps coming up in discussions whenever we talk about needing a keyword for something, in order to make that feature available in all editions. Nominating for discussion. |
I also found myself surprised when I recently reviewed a PR that stabilized something mostly only on an edition boundary. |
Reserve
k#keyword
in edition 2021 and beyond as a general syntax for adding keywords mid-edition instead of needing speculative reservations.Rendered