Why do some folks dislike shadowing? I think it's an amazing feature.
Hello,
I've seen many folks say that they dislike rust's shadowing, and it causes bugs for them.
While I find them extremely useful.
Some detractors:
- https://stackoverflow.com/questions/59860476/what-is-the-rationale-behind-allowing-variable-shadowing-in-rust
- https://internals.rust-lang.org/t/we-need-a-variable-shadowing-suppression-option/12339
- https://internals.rust-lang.org/t/history-of-shadowing-in-rust/6441
I find shadowing useful for many things:
- Converting mutable variables to immutable, so we can use them without worrying about modifying them. i.e \
let x = x;\\. I wished this feature existed in C++ and other languages. This makes writing mathematical code safe. In languages like Fortran, everything in scope is variable, thus it becomes very difficult to understand which variables need to be modified, and which remain constant. Shadowing makes this extremely easy. - Renaming variables for quick development/debugging. Often we inherit code from someone else, and we do not like their variable names. While \
cells\\_on\\_flight\\_surface\\is a valid name, I would like to shorten it to \cfs\\to quickly finish my work. In C++, we can use references, but since in Rust, long lived references cause issues with borrow checker, I like to shadow them. Then once my work is done, rename them to their original name. - Error handling. If I need to handle any error, and can not propagate it up the stack with \
?\\, I like to use shadowing for it. \let err = something();\\then handle the error, then shadow \err\\for handling the next errors. \let err = something\\_else();\\ - In small sections of code, shadowing helps write "cleaner" code. \
for x in x.iter() { foo(x); }\\is a good example. While this maybe controversial, I think shadowing makes it more easy for me to understand the code. Another example would be for mathematics/science, we often use the same symbols for different things, so shadowing helps. - EDIT: Another very important use of shadowing that I forgot to mention, is to temporarily fix borrow checker issues. If \
let node = &mut something();\\causes issues, due to node being a long lived reference, I can simply shadow it, i.e \let node = 99;\\to fix the issue. While I do not consider this to be "good" code, it is helpful to temporarily fight the borrow checker.
My view is: Although shadowing can cause confusion for some folks, I find them extremely useful, and they're one of my most loved features in rust.