From dev-return-7213-archive-asf-public=cust-asf.ponee.io@groovy.apache.org Wed Dec 2 23:24:42 2020 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mxout1-he-de.apache.org (mxout1-he-de.apache.org [95.216.194.37]) by mx-eu-01.ponee.io (Postfix) with ESMTPS id 4F20D180643 for ; Thu, 3 Dec 2020 00:24:42 +0100 (CET) Received: from mail.apache.org (mailroute1-lw-us.apache.org [207.244.88.153]) by mxout1-he-de.apache.org (ASF Mail Server at mxout1-he-de.apache.org) with SMTP id 51B12675E7 for ; Wed, 2 Dec 2020 23:24:41 +0000 (UTC) Received: (qmail 59706 invoked by uid 500); 2 Dec 2020 23:24:40 -0000 Mailing-List: contact dev-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list dev@groovy.apache.org Received: (qmail 59694 invoked by uid 99); 2 Dec 2020 23:24:40 -0000 Received: from spamproc1-he-fi.apache.org (HELO spamproc1-he-fi.apache.org) (95.217.134.168) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Dec 2020 23:24:40 +0000 Received: from localhost (localhost [127.0.0.1]) by spamproc1-he-fi.apache.org (ASF Mail Server at spamproc1-he-fi.apache.org) with ESMTP id 425E8BFD6E for ; Wed, 2 Dec 2020 23:24:39 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamproc1-he-fi.apache.org X-Spam-Flag: NO X-Spam-Score: 2.712 X-Spam-Level: ** X-Spam-Status: No, score=2.712 tagged_above=-999 required=6.31 tests=[HTML_MESSAGE=0.2, KAM_DMARC_STATUS=0.01, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_SORBS_WEB=1.5, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-he-de.apache.org ([116.203.227.195]) by localhost (spamproc1-he-fi.apache.org [95.217.134.168]) (amavisd-new, port 10024) with ESMTP id MdjRwBv_mXvb for ; Wed, 2 Dec 2020 23:24:38 +0000 (UTC) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=217.198.120.70; helo=smtp-beta-2.zoner.com; envelope-from=ocs@ocs.cz; receiver= Received: from smtp-beta-2.zoner.com (smtp-beta-2.zoner.com [217.198.120.70]) by mx1-he-de.apache.org (ASF Mail Server at mx1-he-de.apache.org) with ESMTPS id D40247F863 for ; Wed, 2 Dec 2020 23:24:37 +0000 (UTC) Received: from smtp.zoner.com (smtp.zoner.com [217.198.120.6]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp-beta-2.zoner.com (Postfix) with ESMTPS id ED60F1800139; Thu, 3 Dec 2020 00:24:30 +0100 (CET) Received: from macbook-pro.ocsluj (smtp2stechovice.cli-eurosignal.cz [77.240.99.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: ocs@ocs.cz) by smtp.zoner.com (Postfix) with ESMTPSA id 7204C3000075; Thu, 3 Dec 2020 00:24:30 +0100 (CET) From: OCsite Message-Id: <7EB2B2EC-B9CC-4505-AD1B-B5B07209E675@ocs.cz> Content-Type: multipart/alternative; boundary="Apple-Mail=_8C682937-B962-4FCB-A40F-8124F12E585F" Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: Local variable declaration enhancements -- statement scoping Date: Thu, 3 Dec 2020 00:24:29 +0100 In-Reply-To: <2b18e59c-8a25-041b-5916-0ae7d5955bb5@arscreat.com> Cc: dev@groovy.apache.org To: MG References: <2b18e59c-8a25-041b-5916-0ae7d5955bb5@arscreat.com> X-Mailer: Apple Mail (2.3608.80.23.2.2) --Apple-Mail=_8C682937-B962-4FCB-A40F-8124F12E585F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 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 =E2=80=94 the danger you do = that inadvertently and mess up your code is nonzero, but extremely = small; - if you happen to need that =E2=80=94 typically, if you are = copy-pasting some well-tested inner code into another method =E2=80=94 = 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 =E2=80=94 = like i, j, k etc. for indices used in small loops etc. =E2=80=94 than = using i here, i1 there, i2 in just another place, all messing up the = code mightily, without any proper reason =E2=80=94 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 =E2=80=9Clet's try to prevent the programmer shooting his own leg = by crippling his gun=E2=80=9D 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 =E2=80=94 and get rid of = them in Groovy, in my personal opinion :) All the best, OC > On 2 Dec 2020, at 23:33, MG wrote: >=20 > Hi OC, >=20 > 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 ;-) ). >=20 > 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) >=20 > Cheers, > mg >=20 >=20 > On 02/12/2020 18:13, OCsite wrote: >> Hello there, >>=20 >> 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: >>=20 >> =3D=3D=3D >> 89 ocs /tmp> > def i=3D0 // outer >> println "i=3D$i (outer)" >> for (int i=3D1 /* inner */;i<2;i++) println "i=3D$i (inner)" >> println "i=3D$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=3D1 /* inner */;i<2;i++) println "i=3D$i (inner)" >> ^ >> 1 error >> 90 ocs /tmp> >> =3D=3D=3D >>=20 >> This is how it should work: >>=20 >> =3D=3D=3D >> 90 ocs /tmp> > #include >> int main() { >> int i=3D0; >> printf("i=3D%d (outer)\n",i); >> for (int i=3D1 /* inner */;i<2;i++) printf("i=3D%d (inner)\n",i); >> printf("i=3D%d (outer again)\n",i); >> return 0; >> } >> 91 ocs /tmp> cc -Wall q.c && ./a.out =20 >> i=3D0 (outer) >> i=3D1 (inner) >> i=3D0 (outer again) >> 92 ocs /tmp>=20 >> =3D=3D=3D >>=20 >> Thanks and all the best, >> OC >>=20 >>> On 2 Dec 2020, at 17:34, Milles, Eric (TR Technology) = > = wrote: >>>=20 >>> 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. >>> =20 >>> for (int i =3D ...; ...) { >>> // i available >>> } >>> // i unavailable >>> =20 >>> for (x in y index i) { // from Gosu = (http://gosu-lang.github.io/docs.html = ) -- an alternative to using = eachWithIndex >>> } >>> =20 >>> if (x instanceof T t) { // from Java 14+ >>> } >>> =20 >>> if (def x =3D ...) { // tests Groovy truth in this form; may be = wrapped in parens to check something else about "x" >>> } >>> =20 >>> try (def ac =3D ...) { >>> } >>> =20 >>> 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 = >=20 --Apple-Mail=_8C682937-B962-4FCB-A40F-8124F12E585F Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 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 =E2=80=94 the = danger you do that inadvertently and mess up your code is nonzero, but = extremely small;
- if you happen to = need that =E2=80=94 typically, if you are copy-pasting some well-tested = inner code into another method =E2=80=94 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 =E2=80=94 = like i, j, k etc. for indices used in small loops etc. =E2=80=94 than = using i here, i1 there, i2 in just another place, all messing up the = code mightily, without any proper reason =E2=80=94 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 =E2=80=9Clet's try to prevent the = programmer shooting his own leg by crippling his gun=E2=80=9D 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 =E2=80=94 and get rid of them in Groovy, in my personal opinion = :)

All = the best,
OC

On 2 Dec 2020, at 23:33, MG <mgbiz@arscreat.com> = wrote:

=20 =20
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:

=3D=3D=3D
89 ocs /tmp> <q.groovy
def i=3D0 // outer
println "i=3D$i (outer)"
for (int i=3D1 /* inner */;i<2;i++) println "i=3D$i = (inner)"
println "i=3D$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=3D1 /* inner */;i<2;i++) println "i=3D$i = (inner)"
            ^
1 error
90 ocs /tmp>
=3D=3D=3D

This is how it should = work:

=3D=3D=3D
90 ocs /tmp> <q.c
#include <stdio.h>
int main() {
  int i=3D0;
  printf("i=3D%d (outer)\n",i);
  for (int i=3D1 /* inner */;i<2;i++) printf("i=3D%d (inner)\n",i);
  printf("i=3D%d (outer again)\n",i);
  return 0;
}
91 ocs /tmp> cc -Wall q.c && = ./a.out                    =  
i=3D0 (outer)
i=3D1 (inner)
i=3D0 (outer again)
92 ocs /tmp> 
=3D=3D=3D

Thanks and all the best,
OC

On 2 Dec 2020, at 17:34, Milles, Eric (TR Technology) <eric.milles@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 =3D ...; ...) {
  // i available
=
}
// i unavailable
 
for (x in y index i) { // from Gosu (http://gosu-lang.github.io/docs.html) -- an alternative to using eachWithIndex
}
 
if (x instanceof T t) { // from Java 14+
}
 
if (def x =3D ...) { // tests Groovy truth in this form; may be wrapped in parens to check something else about "x"
}
 
try (def ac =3D ...) {
}
 
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/discl= osures.html



= --Apple-Mail=_8C682937-B962-4FCB-A40F-8124F12E585F--