Rebol's designer called this "definitional scoping". What it means is that where a word (variable) exists is important. The "where" part leads to https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-co... and is one of the big things that messes with your head when you come to Red from other langs. :^) For many people this stays invisible forever and things just work. But it doesn't take much for people to step off the ledge and into deep water, because things look so easy and it seems like you should be able to just pass blocks around and have everything work magically. It's internally consistent in how it works, but that's hard to see without tooling we have yet to build.
Rust's `macro_rules!` macros operate on ASTs, so the `x` inside a macro definition is different to the `x` in the scope where the macro is used, even though the textual representation of the identifier the macro inserts into the place it's used might be identical. This means that:
macro_rules! add_two {
($i: ident) => {
let x = 2;
$i += x;
}
}
fn main() {
let mut x = 5;
add_two!(x);
println!("{}", x);
}
appears to become: fn main() {
let mut x = 5;
let x = 2;
x += x;
println!("{}", x);
}
but it still prints 7, not 4, because they're two different `x`s. (Of course, Red has first-class metaprogramming, so it's a lot better.)