3 ms·
Why is variable shadowing a widely accepted thing?
In any dynamic language (e.g. Python), everyone agrees that the following is a Bad Thing (tm).
total = [42, 13, 57] # it's a bird, er uh list
total = sum # it's a plane, er uh int
total = f'{sum'} # it's a supervar!, er uh str
And when I talk to functionary zealots, they like to point out that assigning a variable to different values (even of the same type) violates everything we learned in school about math.
x = 57 - 42
x = 13 # but wait, I thought x was 14. I'm so confused now
Given these sentiments, why do the cadre of mainstream popular languages embrace Variable shadowing (https://en.wikipedia.org/wiki/Variable_shadowing)?
I would have thought that as computer languages became more interested in "correctness", that this loophole for cognitive confusion (and even unexpected behavior/bugs) would be discouraged or even disallowed.
- marceloabsousa 6y agoIt's not a widely accepted thing :)
- travisgriggs 6y agoIt isn't? I deal with it all the time in Kotlin and Swift. Look at the Wikipedia wage. Examples of how it's done in most mainstream languages there.
- uberman 6y agoAre you complaining about variables being shadowed or mutable? Your complaint seems to be about the first but the examples about the second. Note that any good linter will warn you about shadowing even if it is technically allowed by the language.
- travisgriggs 6y agoI'm not sure what I'm complaining about. :) I'm still trying to form my argument I guess. I think you're correct that I'm using conflicting examples. I should have left the functional part out. And the other example is one that is only applicable in that it invokes the same sense "it's bad when you look at a variable (mutable or not) and don't really know what you're looking at, but have to reinterpret the context leading up to the use to figure out what it is". Take the following guts of a Kotlin method body I just stumbled on: upgradeStream?.bytesReceived = ubytes.copyOfRange(0, 2).le.ushort this.binding.progressBar.updateProgress(upgradeStream?.progress ?: 0.0f) val upgradeStream = this.upgradeStream ?: return if (upgradeStream.areAllBytesSent) { upgradeStream.sendEndUpgrade() } else { upgradeStream.sendNextSentence() } Depending on where I'm at in this flow of code, `upgradeStream` is a different thing.
- philipkglass 6y agoThe most common reason I would have variable shadowing in my code is that I'm dealing with optional values. e.g. (Scala) def greeting(name: Option[String]): String = name match { case Some(name) => s"Hello $name" case None => "Welcome, stranger" } I could call the input parameter something like optionalName or maybeName to avoid shadowing but I dislike repeating type information in the variable name.