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 <[email protected]>
Sent: Friday, September 5, 2025 10:02 AM
To: Groovy_Developers <[email protected]>
Cc: Milles, Eric (TR Technology) <[email protected]>
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 <[email protected]>
Sent: Thursday, September 4, 2025 5:54 PM
To: Groovy_Developers <[email protected]>
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>

Reply via email to