The idea is mainly come from Exclamation ! mark ! for ! macros ! feels ! kinda wrong? - The Rust Programming Language Forum, it might be better to discuss about the future syntax of macros.
The reason I prefer println{...}
is three fold:
Firstly, it would save a !
, and typing println{}
won't be more difficult than typing println()
.
Secondly, {}
could provide more than what !
provides, !
could only suggests that is a macro, but {}
would further suggests things in this bracket is a new grammar.
A famous grammar in the curly brackets is, default constructor:
Foo{field:42}
Here, we use :
, rather than =
, as the assigment expression, which might be regard as a new grammar. If we unify the macro's keyword{}
and struct's StructName{}
, we could regard the latter one as a macro, and people could wrote new StructName
macros to expand the function of old macros.
Here, we could make a new expand macro like:
expand_macro_rules! exist_macro potential_new_macro_name {
// new rules
}
if potential_new_macro_name
is not provided, expand_macro_rules
would override (actually expand) the current exist macro in current crate. when old macro failed to match, it would try matching new rules.
If we have the new macro system, we could introduce more initialize methods more than Foo{field:42,..Default::default()}
Last but the most important, curly brackets allow us expand Rust's syntax directly. For example, suppose we are in Rust 2015 and async is not a keyword yet, when we want to add async
syntax, we could define a macro async
, and wrote
async{...}
directly.
further, we could further allow macro combinations, which could allow us write macros like
do {
body
} while {cond}
If we allow write extra parameters after macro keyword (rather than type {
immeditely, in this case, we might want an additional !
(which is what currently macro_rules!
's grammar)), we could wrote
while! cond {
body1
} else {
body2
}
the latter code could be translate to
loop {
if cond {
body1
} else {
break body2
}
}
directly.
Is this idea worth discussion?
Is there any disadvantages introduce the new syntax?
update:
for naming confliction, there might be several solutions:
- add
macro
keyword when necessary:
macro 宏 {...} // for languages could not perform snake_case convertion, add a macro keyword
println {...} // it compiles, but it is not very necessary to add the macro hint, since `println` is already snake_case.
macro MacroWithUnusualNaming {} // this seems to be a struct, but if it is indeed a macro, use `macro` keyword.
- add
::
or<>
for constructors
Vec::{iter:my_iter}
Vec::<_>{iter:my_iter}
most cases, add macro
keyword when necessary is enough, and people may forgot add macro keyword since there is no need to add this keyword in most of cases.
But if someone really want to argue about macro
keyword, the turbofish symbol might be a good alternative. Since we could not construct structs with a private field with grammar Struct{...}
now, add some extra symbol might not cost a lot.
What's more, we could just type ::{...}
and let the compiler guessing the correct type.
struct Foo{};
impl Foo {
fn new()->Self {
::{} // Foo{}
}
}