|
|
|
|
|
by greggirwin
1795 days ago
|
|
One of our team summed it up very nicely: Pragmatically, this design notion comes from Red being a data format first (code is data and data can be used as code). To mimick scoping at data level, context has to be implicit. As a consequence, any block of code e.g. [take the spoon] can be passed around, evaluated on demand in any place, used in user-defined custom loops, without losing the original meaning even if all it's words `take`, `the` and `spoon` were defined differently in those loops or other functions. 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:
appears to become: 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.)