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

Disable macro hygiene #2054

Closed
jD91mZM2 opened this issue Jul 4, 2017 · 11 comments
Closed

Disable macro hygiene #2054

jD91mZM2 opened this issue Jul 4, 2017 · 11 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@jD91mZM2
Copy link

jD91mZM2 commented Jul 4, 2017

Not sure how the best way to do it would be, but it would be awesome to be able to disable macro hygiene.

macro_rules! test {
    () => raw {
        val = 42;
    }
}

let mut val = 0;
test!();
// val = 3

This would be useful to create global macros that can still access local variables.
We should consider making you call the macro with two exclamation marks to really make sure you know you are calling a raw macro - though, you decide on that one. I'm personally against it.

@est31
Copy link
Member

est31 commented Jul 4, 2017

Local macros can access local variables. You can do sth like:

macro_rules! test_raw {
    ($val:ident) => raw {
        $val = 42;
    }
}

fn foo() {
    let mut val = 0;
    macro_rules! test {
        () => {
            test_raw!(val);
        };
    }
    test!();
    // val = 3
}

This is what I do when I don't want to write val too much.

The current situation is fine IMO.

@jD91mZM2
Copy link
Author

jD91mZM2 commented Jul 4, 2017

I usually do

macro_rules! make_test() {
    ($val:ident) => {
        macro_rules! test() {
            () => {
                $val = 42;
            } 
        }
    }
}

fn foo() {
    let mut val = 0;
    make_test!(val);
    test!();
    // val = 3
}

So yeah, same thing. But still it would be better if you could just disable it completely.

@KalitaAlexey
Copy link

KalitaAlexey commented Jul 4, 2017

I'm against it because it increases complexity of macros with no benefit (which cannot be achieved in other ways).
@legolord208,
Your example is very good.
You use macros like functions.
Global variables is an anti-pattern.
For macros without hygiene local variables are global.
In your example you pass the variables so it works.

@jD91mZM2
Copy link
Author

jD91mZM2 commented Jul 4, 2017

While I agree to that argument, code can also become messier without it.

@davemilter
Copy link

While I agree to that argument, code can also become messier without it.

Strongly disagree. Macros that change context without any hint about this - this is make code messier.
It is like functions that works global variables, but worst, because it changes not unique variable, but all with some name.

@petrochenkov
Copy link
Contributor

This is going to be done in macros 2.0 on per-identifier basis, e.g. like this:

macro test() {
    #val = 42; // mark val as unhygienic
}

let mut val = 0;
test!();
assert_eq!(val, 42);

This is not implemented yet, but see some discussion in rust-lang/rust#40847.

@est31
Copy link
Member

est31 commented Jul 4, 2017

@petrochenkov is that really the final conclusion? How is that any better from the current macro system? Through the messaging, I've thought hygienic macros were something that Rust does better than other languages, not something it should be ashamed of?

@petrochenkov
Copy link
Contributor

@est31

is that really the final conclusion?

No :)
But it's a likely course of action.

Macros 2.0 (macro) as currently implemented show how useless fully hygienic macros are. You can't even generate an item visible outside of the macro! Some kind of opt-out is necessary.

@est31
Copy link
Member

est31 commented Jul 4, 2017

@petrochenkov from how I read the discussion, breaking hygiene this way is not meant to be supported. E.g. the PR description explicitly says that the "Breaking Hygiene" section of the Racket macro hygiene system doesn't apply here. The uses of # that I could see in the discussion all concerned stuff being exported to be visible outside of the macro, so the rules got stricter, not less strict.

@est31
Copy link
Member

est31 commented Jul 4, 2017

Note that I do support # being mandated for exporting stuff from a macro, but there should be no way to import stuff to a macro from the call site. Importing from the definition site, maybe with mandated #, is okay.

@jD91mZM2
Copy link
Author

jD91mZM2 commented Jul 4, 2017

If they're already being discussed, I will happily close this issue. Thanks for the heads up, @petrochenkov :)

@jD91mZM2 jD91mZM2 closed this as completed Jul 4, 2017
@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label Feb 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

6 participants