Hi OC,
@Shadowing local variables is a normal and very reasonable thing which
worked perfectly and without a glitch from the Pascal up, or perhaps
even Algol, I am not quite sure, it's far far ago :) Forbidding it is
wrong, for it prevents e.g. copy/pasting small code snippets which just
happen to contain an inner variable (most typically something like for
(int i...) which just happens to be used in the code into which the
snippet goes as well. The developer is then forced to change the old and
well-tested code renaming the variable, which for one takes time which
can be used much better elsewhere, what's worse, it brings a danger the
changes would cause new bugs:
1. As someone who always thought allowing shadowing of local variables
was a bad idea, I would challenge that statement ||-)
2. As for your example of copy & pasting a code snippet:
1. I paste the snippet into a text editor to search & replace the
colliding variable name in that scenario, manually confirming
every replace.
1. I have done this many times over the years, and that has
never lead to the introduction of any bugs.
2. In addition, since all the names used in the snippet will
typically not follow ones own coding/naming convention, this
must be done in any case, most of the time.
2. Alternatively one could always put the snippet into a seperate
method, to avoid any name collisions...
Cheers,
mg
Am 07.09.2025 um 15:20 schrieb Ondra Cada:
Jochen,
On 7. 9. 2025, at 13:05, Jochen Theodorou <blackd...@gmx.org> wrote:
On 05.09.25 18:10, OCsite wrote:
[...]
===
def foo // [1]
...
for (def foo in ....) // would not use [1], would scope a new
variable instead
for (foo in ...) // would use [1]
===
If you are cosy with breaking backward compatibility, well, you
should do /this/ change, not /that/ one which breaks it for no
benefit at all.
the first for-loop must not compile
It does, since [1] happens to be a property :)
because it would invalidate how local variable scoping works in
general: we do no allow shadowing of local variables, every local
variable name must be unique!
Quite. That's another very bad thing which should be fixed to work the
way normal languages (which obviously does not include Java[*]) always
did.
Shadowing local variables is a normal and very reasonable thing which
worked perfectly and without a glitch from the Pascal up, or perhaps
even Algol, I am not quite sure, it's far far ago :) Forbidding it is
wrong, for it prevents e.g. copy/pasting small code snippets which
just happen to contain an inner variable (most typically something
like for (int i...) which just happens to be used in the code into
which the snippet goes as well. The developer is then forced to change
the old and well-tested code renaming the variable, which for one
takes time which can be used much better elsewhere, what's worse, it
brings a danger the changes would cause new bugs :(
Note also this creates another weird inconsistence — with the default
it, Groovy does support shadowing all right; try e.g.,
===
2.times {
println "outer it=$it"
666.each {
println "inner it=$it"
}
println "outer it back to $it, as it should!"
}
===
I'ts completely strange and counter-intuitive that soon as I use an
explicit declaration (e.g., just { int it ->, to make sure the type's
right, without touching the inner code inside of the closure), I'm SOL.
That's patently wrong. This is precisely one of those many things
which Java designers did not do right. [*]Groovy is here to fix Java
design bugs and inconveniences — if Java was perfect, after all,
Groovy would never have a reason to exist —, and it very definitely
should fix this one as well. This fix would not even break any
backward compatibility; it would simply allow code which sometimes
might be highly beneficial and so far was forbidden.
But that is besides the point of if the for-loop spawns a new local
scope or not.
Quite :) That's why, in my original example, the local scope shadowed
a property and not another local variable :)
Thanks and all the best,
OC