> On 5. 9. 2025, at 19:33, Milles, Eric (TR Technology) > <eric.mil...@thomsonreuters.com> wrote: > > Well there's a difference betwixt “no example” and “no known example” > Not sure I get the semantic difference in your statement.
The difference is that there's always a possibility a feature is used in someone's codebase. Even though [*] he for any reason does not observe the development of future versions and does not check thoroughly whether they might or might not break it. [**] You should never make breaking changes (like disabling features), unless there's a really big gain. (Of course, since I do not work on the parser, I can't see whether it is considerably simpler/faster thanks to ignoring/enforcing def in fors. Perhaps it simplified/sped up it enough to make it well worth the change. From the developer's POV though there's no gain at all, quite the contrary.) > As I said, using a closure was what I was trying to prevent. Here you lost me completely. So far in this debate, there was no closure mentioned/used from my side at all, or did I overlook something? > Now that I see Groovy and Java support variables and fields in this way: > https://github.com/apache/groovy/pull/2289 So c-style for actually still works with external variables? If so, great! And if for/in could, it would be even better (for me; I could see that it might make a breaking change for others, and we are back at [**], of course). > If devs could take an earlier look at the alphas and betas, we could avoid > this kind of thing. This change was in beta-2. [*] eg., myself, at the moment, I can't even reasonably try G5 with our projects (unless I create a separate testing site), for my client still insist on Java 8, which he considers stable enough — 11 is still far too new for him :) Thanks and all the best, OC > > From: OCsite <o...@ocs.cz> > Sent: Friday, September 5, 2025 12:20 PM > To: Milles, Eric (TR Technology) <eric.mil...@thomsonreuters.com> > Cc: dev@groovy.apache.org <dev@groovy.apache.org> > Subject: [EXT] Re: Ugly inconsistence betw. for and for/in > > External Email: Use caution with links and attachments. > > There were no examples of this sort of usage > > Well there's a difference betwixt “no example” and “no known example” :) > > For me, the following used to be comparatively common: > > 1. I create a web component which uses a web-iterated index, and there's a > non-trivial functionality related to the index. Something like this > (simplified for a short example, in reality there would be considerably more > complex index-based functionality than just the nameAtIndex below): > > === code part > def index, list=... > def nameAtIndex() { def item=list[index]; > item.title?:item.description?:item.toString() } > === web part > <wo:repeat index="$index" count="$list.count"><wo:string > value="$nameAtIndex"/></wo> > === > > 2. later I bump to a need to iterate programmatically reusing the added > functionality. > > Instead of fully refactoring the code (which would be definitely better, but > there might not be time enough for that), I often simply reuse the existing > code as-is: > > === [current-case] > for (index=0; index<list.count; index++) println nameAtIndex() // works like > a charm > === > > Now it so happened my iterable was not index-based, but list-based, like this: > > === code part > def item, list=... > def itemName() { item.title?:item.description?:item.toString() } > === web part > <wo:select list="$list" item="$item" displayName="$itemName"/> > === > > thus my reuse-the-existing-code attempt was quite nicely plain: > > === [possible-case] > for (item in list) println itemName() // does not work at all, alas > === > > and I've been pretty surprised it does not work as expected. Took me some > time to find that although I did not write for (def item in list), I still > must use (luckily one-liner) boilerplate which definitely should not be > needed here: for (def x in list) { item=x; ... } :( > > Now I sort of fear in future, when I upgrade to G5, I will have to re-write > in a similar way all the [current-case] cases in all my projects. > > Quite the contrary, it would be definitely nice if in future I could use > [possible-case], too. > > All the best, > OC > > On 5. 9. 2025, at 18:12, Milles, Eric (TR Technology) > <eric.mil...@thomsonreuters.com> wrote: > > The intention was not to "cripple" anything. There were no examples of this > sort of usage and allowing arbitrary expressions, like closures, was strange > at first glance. It is quite costly for the parser to explore so many > alternatives at the start of the for statement. > > https://github.com/apache/groovy/pull/2174 > <https://urldefense.com/v3/__https://github.com/apache/groovy/pull/2174__;!!GFN0sa3rsbfR8OLyAw!cSf5ecC1uPAC91ntDj408mMdtqkqAs4k05POLWowr_oSSfjSV71uRVkIP52dDaP2UnTcnQkuXLkUisvB-A$> > > It was discussed that old scripts might use "for (v = 1; ...; ...)" to > interact with the script binding. We did not have examples at the time of > declaring variable(s) outside of the loop statement and then referencing them > in the initialization segment. > > If this change is reversed for 5.0.1, it would not change the "strange" > difference between classic for and enhanced for in terms of variable > declaration vs. reference when no type is given. > > > From: OCsite <o...@ocs.cz> > Sent: Friday, September 5, 2025 11:01 AM > To: dev@groovy.apache.org <dev@groovy.apache.org> > Cc: Milles, Eric (TR Technology) <eric.mil...@thomsonreuters.com> > Subject: [EXT] Re: Ugly inconsistence betw. for and for/in > > External Email: Use caution with links and attachments. > > P.S. > > it's quite unfortunate to cripple the language by forbidding that > > among others also since it would break legacy code which relies on [1] — > without any gain for that :( > > All the best, > OC > > On 5. 9. 2025, at 17:55, OCsite <o...@ocs.cz> wrote: > > Well I would argue that's terribly wrong, for it does not bring any new > functionality, just limits the existing one. Sometimes the form > > === > def foo, bar // [1] > ... > for (foo=1, bar=2, ....) // works with the very variables [1] > === > > makes perfect sense and it's quite unfortunate to cripple the language by > forbidding that :( And when the user does not want to use existing variables, > nothing easier (and more logical and intuitive) than simply adding def. > > All the best, > OC > > On 5. 9. 2025, at 17:17, Milles, Eric (TR Technology) via dev > <dev@groovy.apache.org <mailto:dev@groovy.apache.org>> wrote: > > NOTE: Groovy 5 removes the expression list support from the first part of a > classic form — variable declaration is the only option. > > So, "for (foo = 1, bar = 2;' ...; ...)" is no longer possible. You must > write "for (def foo = 1, bar = 2; ...; ...)" or "for (def (foo,bar) = [1,2]; > ...; ...)". > > > forControl > : enhancedForControl > | originalForControl > ; > > enhancedForControl > : (indexVariable COMMA)? variableModifiersOpt type? identifier (COLON | IN) > expression > ; > > indexVariable > : (BuiltInPrimitiveType | DEF | VAR)? identifier > ; > > originalForControl > : forInit? SEMI expression? SEMI forUpdate? > ; > > forInit > : localVariableDeclaration > ; > > forUpdate > : expressionList[false] > ; > > > > From: Milles, Eric (TR Technology) via dev <dev@groovy.apache.org > <mailto:dev@groovy.apache.org>> > Sent: Friday, September 5, 2025 10:02 AM > To: Groovy_Developers <dev@groovy.apache.org <mailto:dev@groovy.apache.org>> > Cc: Milles, Eric (TR Technology) <eric.mil...@thomsonreuters.com > <mailto:eric.mil...@thomsonreuters.com>> > Subject: Re: Ugly inconsistence betw. for and for/in > > for-each and for-in always declare a new collection variable, which may have > its type elided. And now an index variable is also supported. > > def foo = null > for (foo : []) {} > for (foo in []) {} > > should produce an error of duplicate variable declared in outer scope. > > > for (classic) is a sequence of three expressions. I don't think there is a > hard requirement of a variable declaration expression as the first > expression. So "foo = 1" is seen as an assignment not a declaration. There > may be some history where the variables were all set into script binding > > > > From: Ondra Cada <o...@ocs.cz <mailto:o...@ocs.cz>> > Sent: Thursday, September 4, 2025 5:54 PM > To: Groovy_Developers <dev@groovy.apache.org <mailto:dev@groovy.apache.org>> > Subject: [EXT] Ugly inconsistence betw. for and for/in > > External Email: Use caution with links and attachments. > > Hi there, > > I've just bumped into the problem that the c-like for properly scopes/does > not scope based on whether its control variable is declared or just used, > whilst for/in always scopes, regardless the form (see the example below for > detailed explanation). > > Is this a bug or an intended behaviour? > > It would be nice to fix it so that for/in does not scope when there's no > declaration, but I fear it might be a breaking change for legacy code :( > > Thanks and all the best, > OC > > === > 5 ocs /tmp> <q.groovy > class Foo { > def foo > def bar() { println "foo='$foo'" } > def test() { > println "Should not change" > for (def foo in [1,2]) bar() > println "Precisely like does not here" > for (def foo=1; foo<3; foo++) bar() > println "Should change but does not" > for (foo in [1,2]) bar() > println "Precisely like does here" > for (foo=1; foo<3; foo++) bar() > } > static main(args) { > Foo.newInstance().test() > } > } > 6 ocs /tmp> groovy q > Should not change > foo='null' > foo='null' > Precisely like does not here > foo='null' > foo='null' > Should change but does not > foo='null' > foo='null' > Precisely like does here > foo='1' > foo='2' > 7 ocs /tmp> groovy -version > Groovy Version: 4.0.27 JVM: 1.8.0_452 Vendor: Tencent OS: Mac OS X > 8 ocs /tmp> > >