Hi OC,
1. Is there a reason you cannot put your "well-tested inner code" in a
seperate method, thereby making the code cleaner and avoiding the
name clash problem altogether ? In any case that is not a strong
argument in my eyes: Just copy & paste the code into a seperate
editor and search & replace all clashing variable names, or put it
into a seperate method temporarily and use your IDE's renaming
support to change the variable names - this should take less than a
few minutes, and how often do you really encounter that scenario in
practice ?
2. You example of using it in closures makes no sense to me, since "it"
in a closure always refers to the one closure argument, so a new
closures it will always hide any enclosing closures it. At the same
time "it" in closures is typically only used for very compact
closure bodies, often single statetments, so there is never any
danger of confusing what the it refers to.
3. This is in my experience absolutely not the case for any larger
piece of code, so let's agree to differ on whether masking variables
in general is a good idea or not :-)
Cheers,
mg
On 03/12/2020 00:24, OCsite wrote:
MG,
the idea is very plain:
- if you don't need to nest same-named variables, there's no harm, you
just don't do that, and all's well and swell — the danger you do that
inadvertently and mess up your code is nonzero, but /extremely/ small;
- if you happen to need that — typically, if you are copy-pasting some
well-tested inner code into another method — you just do that and
don't have to rename. And that's highly desirable, for renaming is
dangerous and error-prone: you rename once-too-many or once-too-less,
and hard-to-find errors ensue.
As for coding style, that's in the eye of the beholder, but in my own
experience, it is considerably better to keep the same approach — like
i, j, k etc. for indices used in small loops etc. — than using i here,
i1 there, i2 in just another place, all messing up the code mightily,
without any proper reason — just forced by the compiler deficiency in
proper nesting.
Incidentally, Groovy sort-of supports this with it: you can write
3.times { // works all right, which is, well... all right :)
println "outer: $it"
it.times {
println "inner: $it all right"
}
}
it is completely absurd and nonsensical that you can /not/ rewrite the
very and completely same code with explicit variables:
3.times { n -> // does not work, which is wrong
println "outer: $n"
n.times { n ->
println "inner: $n oops!"
}
}
This “let's try to prevent the programmer shooting his own leg by
crippling his gun” approach of Java is actually a cause of
/infinitely/ more errors than those it prevents. We should leave it to
Java to cherish its terrible design howlers — and get rid of them in
Groovy, in my personal opinion :)
All the best,
OC
On 2 Dec 2020, at 23:33, MG <mg...@arscreat.com
<mailto:mg...@arscreat.com>> wrote:
Hi OC,
I think that generally speaking, hiding/masking an outer variable
like that is a quite undesireable coding style, so I like the current
Groovy behavior (even if it deviates from C, evidently - I never used
code like that in C, so I did not even know it was valid ;-) ).
What specific use case did you have in mind, where just renaming the
inner variable to i0, j, k, ... or the outer to index, idx, ... would
not be the better solution ?
(I use an informal coding style where I use variable names with a
number at the end for short term / loop / etc variables, and for
parameters and variables who live throughout a method or larger block
I use no number postfix or longer names; the short name / long name
meta at least is quite common, I think)
Cheers,
mg
On 02/12/2020 18:13, OCsite wrote:
Hello there,
when touching this stuff, it would be extremely desirable primarily
to fix the scoping/obscuring of same-named variables, which Groovy
at the moment does wrong, same as the demented Java thing:
===
89 ocs*/tmp>* <q.groovy
def i=0 // outer
println "i=$i (outer)"
for (int i=1 /* inner */;i<2;i++) println "i=$i (inner)"
println "i=$i (outer again)"
89 ocs*/tmp>* /usr/local/groovy-4.0.0-alpha-1/bin/groovy q
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed:
/private/tmp/q.groovy: 3: The current scope already contains a
variable of the name i
@ line 3, column 10.
for (int i=1 /* inner */;i<2;i++) println "i=$i (inner)"
^
1 error
90 ocs*/tmp>*
===
This is how it *should* work:
===
90 ocs*/tmp>* <q.c
#include <stdio.h>
int main() {
int i=0;
printf("i=%d (outer)\n",i);
for (int i=1 /* inner */;i<2;i++) printf("i=%d (inner)\n",i);
printf("i=%d (outer again)\n",i);
return 0;
}
91 ocs*/tmp>* cc -Wall q.c && ./a.out
i=0 (outer)
i=1 (inner)
i=0 (outer again)
92 ocs*/tmp>*
===
Thanks and all the best,
OC
On 2 Dec 2020, at 17:34, Milles, Eric (TR Technology)
<eric.mil...@thomsonreuters.com
<mailto:eric.mil...@thomsonreuters.com>> wrote:
Traditional "for" (first example) and ARM "try" (last example)
support local variable declarations that are scoped to the
statement. In light of the upcoming "instanceof" enhancement in
Java, I was thinking about possible alternatives for declaring
local variables that have statement scope.
for (int i = ...; ...) {
// i available
}
// i unavailable
for (x in y index i) { // from Gosu
(http://gosu-lang.github.io/docs.html
<http://gosu-lang.github.io/docs.html>) -- an alternative to using
eachWithIndex
}
if (x instanceof T t) { // from Java 14+
}
if (def x = ...) { // tests Groovy truth in this form; may be
wrapped in parens to check something else about "x"
}
try (def ac = ...) {
}
This e-mail is for the sole use of the intended recipient and
contains information that may be privileged and/or confidential. If
you are not an intended recipient, please notify the sender by
return e-mail and delete this e-mail and any attachments. Certain
required legal entity disclosures can be accessed on our
website:https://www.thomsonreuters.com/en/resources/disclosures.html
<https://www.thomsonreuters.com/en/resources/disclosures.html>