-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Unify and sweeten the syntax for attributes and macros using the @foo
notation.
#208
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
Closed
Closed
Changes from all commits
Commits
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 hidden or 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,48 @@ | ||
- Start Date: 2014-07-21 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
|
||
Unify and sweeten the syntax for attributes and macros using the `@foo` notation. | ||
|
||
# Motivation | ||
|
||
Currently, attributes and macros/syntax extensions are both conceptually macros: they are user-definable syntactic extensions that transform token trees to token trees. However, their syntaxes are quite different: at present, attributes use `#[attr()]`, while macros use `macro!()`. By switching to a uniform syntax, `@attr()` and `@macro()`, we can emphasize their similarity and save syntactic space. At the same time, we reduce the verbosity of attributes and make them more like other languages by using the `@` notation. | ||
|
||
The `!` and `#` notation take up syntactic space that we may want to use elsewhere. For example, RFC #204 suggests using `!` for a type assertion. | ||
|
||
At least the following languages use `@` notation for attributes: Java (annotations), Python (decorators), D, Dart (metadata), Scala (annotations), and Swift. Languages have generally chosen either `@` or `[]` (brackets) to represent attributes; we cannot choose the latter because of ambiguity with array literals. | ||
|
||
Julia uses `@` for macros. | ||
|
||
Objective-C uses `@` to indicate special notation not in the C language. Since Objective-C is not a macro expander but is a full-fledged compiler, this is not directly analogous. But, in the author's opinion, the `@` sigil has a similar feel in Objective-C. | ||
|
||
# Detailed design | ||
|
||
The following syntactic changes occur: | ||
|
||
* `#[inline]` → `@inline` | ||
* `#[inline(never)]` → `@inline(never)` | ||
* `#[deprecated="May discolor some fabrics"]` → `@deprecated="May discolor some fabrics"` | ||
* `println!("Hello {}", "Niko")` → `@println("Hello {}", "Niko")` | ||
* `vec!["spam", "eggs", "bacon"]` → `@vec["spam", "eggs", "bacon"]` | ||
* `bitflags! { flags Flags: u32 ... }` → `@bitflags { flags Flags: u32 ... }` | ||
|
||
Parsing is slightly complicated because, where an item is expected, the parser does not know whether an item macro or an attribute is next after parsing the leading `@`, identifier, and `(`. Therefore, the parser parses a series of parenthesis-delimited token trees in these cases, and looks at the next token following the `)` to determine whether it parsed an item macro or an attribute. If the next token is `;`, it considers what it just parsed an item. Otherwise, it reinterprets what it just parsed as an attribute. | ||
|
||
# Drawbacks | ||
|
||
* The beauty of `@` vis-à-vis `#`/`!` is in the eye of the beholder. | ||
|
||
* The complication of parsing increases the complexity of the language somewhat and may affect syntax highlighting. (However, this is mitigated to some degree because macros and attributes are already difficult to syntax highlight as a result of their free-form syntax.) | ||
|
||
# Alternatives | ||
|
||
There are innumerable other syntaxes one could consider. Unadorned brackets for attributes, C#-style (e.g. `[inline(never)]`), does not seem possible to reconcile with our array syntax. | ||
|
||
The impact of not doing this is that the current syntax will remain. | ||
|
||
# Unresolved questions | ||
|
||
* `@deprecated="foo"` may be ugly. Should we do anything about this? One possibility is to switch to `@deprecated("foo")`, which is more consistent anyhow. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Emphatically in support of axing |
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.
FWIW, Objective-C does this to maintain C compatibility. It does perhaps have a similar feel, but you do end up with things like
@[@1, @2, @"three", @(YES)]
, i.e. lots of@
repetition, that only exists because of the need for C compatibility.