4 ms·
Variable shadowing is orthogonal to static typing. You can do the exact same thing in OCaml or Haskell - a is being redefined so it can be given any type you wa
by gopiandcode 5y ago
Variable shadowing is orthogonal to static typing. You can do the exact same thing in OCaml or Haskell - a is being redefined so it can be given any type you want.
- Kinrany 5y agoFor unrelated reasons, I wonder how strong Rust's runtime types are. That is, assuming you manage to compile something with undefined behavior, will the program crash immediately?
- ithkuil 5y agoRust undefined behavior can only happen within "unsafe" blocks. You can read more about what things the programmer has to manually avoid while writing code in "unsafe" code blocks: https://doc.rust-lang.org/reference/behavior-considered-undefined.html https://doc.rust-lang.org/reference/behavior-considered-unde... EDIT: this means that if you stick to safe rust, the type system ensures you cannot have data races (among other things)
- Kinrany 5y agoI do mean the unsafe blocks.
- tom_mellior 5y agoIt won't necessarily crash immediately. Inside unsafe blocks you can invoke undefined behavior by overwriting arbitrary memory locations. The effects of reading that modified memory (including crashes) can become visible much later, long after the unsafe block.
- KingOfCoders 5y agoThat answer is technically correct but too shallow. I could then call a = "hallo" // can call String methods, runtime checked a = 3 // can call int methods, runtime checked in Python also variable shadowing. But in this case you assume a is the same but the type changes, and call it dynamic typing, while in the Rust example you assume the two a's are not the same variable: let a = String::from("Hallo"); // can call String methods, compiler checked let a = 3 // can call i methods, compiler checked One could argue there is a difference with method signatures def f( a ) a = "hallo" f(a) a = 3 f(a) which does work in Python ("dynamic") but not in Rust ("static"). But then the actual usage of "a" in the method effectively puts it on the same level as interfaces in Rust and blurs further with static languages like Typescript without nominal types.
- tom_mellior 5y ago> I could then call <variable reassignment> in Python also variable shadowing You could, but you would be wrong. Shadowing is associated with opening a new scope. Reassignment modifies a location in an existing scope. Python does the latter.
- KingOfCoders 5y agoWhat does that mean? Wouldn't scope only come into play with e.g. a = "hello" { // new scope a = 3 } // a == "hello" and is there a difference between Rust and Python?
- valenterry 5y agoI believe the difference is that Rust implicitly creates a new scope when a variable of type X is (re)assigned with a different type. So you in rust you can write (python syntax) a = 3 a = "x" and both of these variables will exist at the same time with different times and potentially referable to from the outside. In python that cannot work, because there are no types. That's why in python the behavior is to always overwrite the existing variable, or create a new one in a local scope _if and only if_ this scope is somehow specified, i.e. by declaring a function.
- gopiandcode 5y agoHere's an example of how the behaviour between Rust and Python differ because of scoping: in Rust: fn main() { let a = 3; let f = | | { a }; let a = "b"; println!("{}, {}", f(), a); } in Python: a = 3 def f (): return a a = "b" print("{}, {}".format(f(), a)) The rust code outputs "3, b" while the python code outputs "b, b". The python code _assigns_ to the variable a, whereas the rust code creates a new scope and redefines a, shadowing it in the parent scope.
- KingOfCoders 5y agoYes you're right, I also would think closures would be impacted by scope.