Hi Eric,
Thanks for raising this on the list, and for the work in
https://github.com/apache/groovy/pull/3054.
I agree that terse Java-style array initializers such as
`int[][] matrix = { {1}, {2}, {3} }` are worth adding. They close a
real gap for people who paste Java snippets, and the non-closure cases
look solid.
On the GROOVY-8561 edge, I am less worried about the empty form
`Closure[] a = {}` becoming a zero-length array than about non-empty
arrowless bodies. Today those store a Closure; under the Java-faithful
reading they can run at initialisation and leave null (or another
scalar) in the array. For example:
Closure[] a = { println('x') }
prints at declaration time and stores [null]. That is a silent
behaviour change, which is harder for callers to detect than a hard
failure. The same class of issue shows up for some Runnable/Callable
(and similar SAM) bodies that are not command chains. COMPATIBILITY
currently documents the empty-{} flip well; it does not yet spell out
this eager-evaluation case.
Arrow forms ({ -> }, { x -> ... }) remain unambiguous, so the escape
hatch for an intentional single-closure array is still available. I do
not think we need to keep array promotion for every arrowless {}
forever, but I would prefer not to break working Closure/SAM/Object
cases quietly.
Two directions that seem workable:
1. Keep the Java-faithful reading, with a stronger COMPATIBILITY note,
an explicit test matrix for {} / { it } / { -> } / { { } } /
Runnable[] / Object[] / @CompileStatic, and ideally a compile-time
diagnostic when a Closure/SAM-typed array element is not clearly a
closure, lambda, or method reference (accepting that dynamic code
cannot be exact, e.g. { getHandler() }).
2. Prefer a type-aware fallback: use the array reading, except when
the initializer is empty or has a single element and the leaf
component type is Closure, a SAM type, or possibly Object — in
those cases keep today's closure promotion. Multi-element and
nested initializers would always be arrays. Nothing that works
today breaks, while Java users still get the forms they actually
paste (String[], int[], int[][], …).
My preference is (2), unless the list is comfortable with (1) plus a
clear diagnostic story. Either way, pinning the chosen semantics with
tests would help a lot.
Happy to follow whatever the list settles on, and to re-review the PR
once the Closure/SAM story is settled.
Cheers,
Daniel Sun
On 2026-10-28 13:53 UTC Milles, Eric (TR Technology) via dev wrote:
> We have been stepping in Java-style array syntax starting in Groovy 3. The
> next step of this support is the terse initialization syntax:
>
> int[][] matrix = { {1}, {2}, {3} }
>
> Without this change, a multi-dimensional array expression requires "new
> int[]" for each sub-array. Or falling back to square-bracket notation.
>
> As discussed in GROOVY-8561, there is one edge case that results in a
> breaking change. When a single value is provided for an array declaration,
> the value is wrapped in an array implicitly: int[] a = 1
>
> The conflict comes when the type supports a closure literal:
> Closure [] a = {}
> Runnable[] b = {}
> String [] c = { print(it) } // not sure what this is for
>
> This can be disambiguated with the addition of an arrow:
> Closure [] a = { -> }
> Runnable[] b = { -> }
> String [] c = { x -> print(x) }
>
> I have made note of this in the COMPATIBILITY document and I don't think this
> pattern is in common usage.
>
> Do you have any comments on the risk of this breaking change? Or do you
> think it is necessary to support array promotion for arrowless closures?
>
> This change is implemented here: https://github.com/apache/groovy/pull/3054
> And was originally proposed here: https://github.com/apache/groovy/pull/691
> 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
>