On 07.09.25 15:20, Ondra Cada wrote:
[...]
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 :(
but if the scope is lexical, then renaming the variables can be done
safe. And then suddenly people want to access variables that are hidden.
What would be the rules? make the symbol the new variable till the end
of the block and in all of its sub blocks?
Like for example
def i = 10
10.times {def i=it+i*i; assert i == it+100;}
assert i == 10
or like... a declaration of a variable makes it existing from there one:
if (true) {
def i = 10
}
assert i == 10
if (false) {
def i = 100
def j = 10
}
assert i == 10
assert j == 10 // error
there are too many possible rules to talk about. Makes no sense if I do
not know which set we are talking about now... and yes... Groovy had
something like the last one initially.... and it was driving the people mad.
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.
I agree, it is a bit counter-intuitive, but it is practical.
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.
I would not say Groovy has a better design than Java. Groovy has
different design goals than Java.
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 :)
that's fine.. well actually it is not really. Not what you did, but that
it breaks the lexical scoping... a bit. and it makes the most problems.
bye Jochen