-
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
Add the experimental_keywords
ability
#2919
Closed
Closed
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
60001f5
first draft of experiemental_keywords
Lokathor 30a2dce
Address https://github.com/rust-lang/rfcs/pull/2919#discussion_r41836…
Lokathor 779b7fe
clarify the rust playground future proposal
Lokathor 3b1b9ad
Clarify that keyword form is intended to be available in all editions…
Lokathor 74ce14c
Add an alterantive where we could limit the experimentation to Nightly
Lokathor 91e0b87
mention rustfix possibility
Lokathor d2b13bd
sysroot possibilty
Lokathor 0c23102
resolve https://github.com/rust-lang/rfcs/pull/2919#discussion_r41874…
Lokathor 0d9adc6
spell out the raw references RFC example in this RFC.
Lokathor 1f4a3a7
Update text/0000-experimental_keywords.md
Lokathor 008bebe
Help clarify RFC scope.
Lokathor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
- Feature Name: `experimental_keywords` | ||
- Start Date: 2020-04-30 | ||
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) | ||
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
This RFC introduce a new way to specify "experimental" keywords. An experimental keyword exposes a fundamental operation of the language and/or compiler _without_ giving that operation its final intended syntax. This allows for user experimentation with the capability introduced by the feature, even on Stable, while allowing the final syntax for the capability to be decided on and stabilized separately from the initial implementation. | ||
|
||
An experimental keyword is given with `r#$keyword`, such as: | ||
* `r#$yeet` | ||
* `r#$assembly_block` | ||
* `r#$raw_ref` | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
It is often the case that we know we want a new ability to be available for users to try out as soon as possible, even before we know what the final syntax for that ability should look like. In the past the compiler has had slightly silly keyword combinations or special proc-macros for this purpose (`do catch` and `await!`). This RFC is a continuation of that idea, while also trying to improve the understanding to general users that the ability they're using isn't in its final form. | ||
|
||
Previously, introducing _any_ new keyword at all had to be done only on an edition change because of the compatibility hazard. Since `r # $ token` is not currently a valid token sequence for anything at all, we can use the `r#$` prefix as a way to "namespace" the experimental keywords away from the main language. | ||
|
||
That said, it will be possible (on a case by case basis) for an experimental keyword available in Nightly to go through the stabilization steps and then be used with the Stable branch. If this happens, the keyword's meaning and usage becomes as fixed as any other Stable part of the language. | ||
* When the final "real" syntax for an experimental feature is stabilized (assuming that it is) the experimental keyword for that feature would continue to work, and code would continue to compile (example: `try!` became the `?` operator). | ||
* It's also possible that the "real" usage of an experimental keyword will be decided to be a proc-macro in the standard library, rather than some bit of syntax (example: the primary way to access inline assembly is not decided on yet, but it's likely to be a proc-macro). | ||
|
||
It is probable that usage of an experimental keyword after the final syntax has been stabilized will fire a warning that you should move to the final syntax, but this can be decided on a case by case basis for each language feature. | ||
* Notably, experimental keywords are intended to be available in all editions, but it's possible that a particular final syntax for a feature might not be usable within all previous editions. In such a case, we would not warn against using the experimental keyword form when the crate was compiling using that older edition. | ||
|
||
--- | ||
|
||
And to be **extra clear** about the scope of this RFC: | ||
* This RFC _only_ proposes that the experimental keywords ability be added to the compiler for use in future language changes and that it be _possible_ for experimental keywords to be stabilized. | ||
* Any actual stabilization of any experimental keyword would have **as high of a burden** as the full normal stabilization process for any other language feature. It would **not** be automatic or assured to happen in any way at all. | ||
|
||
--- | ||
|
||
One concrete example of how experimental keywords could be put into practice is the ["raw references" RFC](https://github.com/rust-lang/rust/issues/64490): | ||
* Essentially everyone agrees that we should offer the ability to directly get a pointer to a field of a struct without an intermediate reference. | ||
* The exact syntax to settle on is up in the air. | ||
* In the mean time people are having to put up with sometimes having unsound code. | ||
* So it's better to make code sound _now_ and make code nice looking _later on_. | ||
|
||
# Guide-level explanation | ||
[guide-level-explanation]: #guide-level-explanation | ||
|
||
From time to time you may see things like `r#$name` in Rust code. These are "experimental keywords". | ||
|
||
An experimental keyword represents accessing the "raw operations" of the compiler and language. They have an intentionally funny syntax because experimental keywords are not intended to be used directly in the long term. Instead, they're a way to add features to the language before we've decided on the final syntax for that feature. | ||
|
||
Most experimental keywords are given a final syntax intended for general, long-term use, some time after the feature itself becomes available in the Stable compiler. This way the Rust community has an opportunity to try it out and see how it feels, how they use it in practice, and so on. Some experimental keywords aren't ever given a direct syntax of their own, instead they're simply there so that proc-macros can expand to code that uses the keyword. | ||
|
||
[And here we'd ideally we'd add at least one or two real examples to the guide once we have some examples of this in practice] | ||
|
||
# Reference-level explanation | ||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
This RFC alters the language so that `r # $ token` is an accepted token sequence. | ||
* It names an experimental keyword named `token`. | ||
* The experimental keyword named _must_ be known to the compiler. If you attempt to name an experimental keyword that the compiler doesn't recognize it is an error. | ||
* The exact meaning and usage for each experimental keyword depends on the language feature it's associated with, and is not specified here. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
* It can slightly hurt Rust's stability story to deliberately introduce new keywords that are intended to become deprecated within a relatively short period of time. | ||
* Mitigation 1: Experimental keywords that do become Stable would continue to work even once the final syntax is decided upon and also stabilized. Stable code would not break. | ||
* Mitigation 2: The rather unusual `r#$` prefix stands out as "clearly unusual" | ||
|
||
# Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
* Alternative: We could select _some other_ sequence of invalid tokens to use as a prefix for experimental keywords. | ||
* `r#$` is used because it is close enough to the "raw literal" and "raw string" syntaxes that people are very likely to understand what's going on even if they're not familiar with a specific experimental keyword when they first see it. | ||
|
||
* Alternative: We could limit the experimental keyword usage to Nightly only until the final syntax is decided upon. | ||
* This would save people who only use the Stable channel from having to worry about using a new feature one way and then potentially being encouraged to update to a second syntax later. | ||
* However, in the 2019 Survey, only 30% of users responded that they use Nightly, so a very large portion of the community would end up excluded from the experimentation phase. | ||
|
||
# Prior art | ||
[prior-art]: #prior-art | ||
Lokathor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
* The Ember framework for JavaScript places experimental framework abilities into a special module that is clearly experimental so that users can try new things and become familiar with new features even before the feature is fully stable. | ||
* There has been some negative experiences elsewhere with exposing things under non-final names, such as [vendor prefixes](https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix) in CSS or [`X-` headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) in HTTP. I think it would be good for them to be mentioned here, with some details about why this won't have those problems. | ||
|
||
# Unresolved questions | ||
[unresolved-questions]: #unresolved-questions | ||
|
||
None at this time. | ||
|
||
# Future possibilities | ||
[future-possibilities]: #future-possibilities | ||
|
||
* It might be desirable to also make an `experiments` crate which can provide various proc-macros that use the experimental keywords. | ||
* We would also ensure that the `experiments` crate is available on the Rust Playground in addition to the "100 most common crates.io crates" that it normally supports. This would help users share ideas and experimental iterations without everyone having to publish their own experimental crates. | ||
* Alternately, the `experiments` crate could simply always be available via the sysroot (like the `proc_macro` crate). | ||
|
||
* It is likely that `cargo-fix` and/or `rustfmt` would be able to automatically convert code using an experimental keyword into the "final syntax" form once a final syntax is decided. | ||
* This would greatly help the transition from experimental keyword to final syntax, but such support would be on a case by case basis. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 think this needs a justification for
$
in particular. Why isr#$
better thanr#@
, say? (Not that I think that one's necessarily superior, just that it's not clearly worse either.)Historically macros have zealously guarded the use of
$
for themselves, and it's not impossible to imagine someone trying to do($mystring:literal) => { r#$mystring }
...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.
Speaking as the RFC author: the current text simply reflects the "first thing that came to mind" during the discussion that lead to this proposal, with not much bike-shedding during that discussion.
Speaking as a user: either way is fine and I have no opinion.
So I'll happily put in whatever people want to decide on for this.
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.
r#$mystring
doesn't work today, and I don't think it will ever work in the future. You can't just stick ar#
next to a lexed token to turn it into a raw string. Macro's use of$
shouldn't really matter here.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.
@kennytm Sure, but macro authors use
$
so commonly that it can cause confusion (they might think thatr#$foo
can work). So why not reduce that confusion by choosing a different character?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.
well for sure there are plenty of alternatives we could choose.
spellings which currently are tokenization error:
r##keyword
r#[keyword]
r#@keyword
/r#!keyword
/ etcr#805209
br#haha_lang_design_go
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.
FWIW,
br#keyword
was also mentioned in #2151.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 only question I have while reading this thread is "why?".
Why come up with these contrived monstrosities messing with lexer if pretty much any combination of two existing keywords would work (
do catch
style)?If you want a generic tool for this (which is, again, excessive in my opinion), make
__experimental
a keyword and use__experimental other_keyword
as the combination.