[ 
https://issues.apache.org/jira/browse/GROOVY-11744?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18015966#comment-18015966
 ] 

Paul King edited comment on GROOVY-11744 at 8/25/25 11:04 AM:
--------------------------------------------------------------

There might be a bug there but it might not be as you expect.

We looked at a lot of usage of dynamic code Groovy where "_" can come from the 
binding (with no declaration) and usage in Jenkins builds and Spock tests. We 
decided upon leaving underscore as a dynamic variable:

https://github.com/apache/groovy/pull/1867#issuecomment-1447527890

That means the following is expected:

{code:groovy}
def method1() {
  def  (_, y, _) = [3, 4, 5]
  println _ // 5, last usage
}
{code}

It was going to break what we believed was valid existing dynamic code if we 
followed Java semantics exactly here.

With CompileStatic, they do act more like unnamed in Java. The binding doesn't 
arise in such code. If you uncomment the last line, it won't compile. That is 
expected.

{code:groovy}
@CompileStatic
def method2() {
  def  (_, y, _) = [3, 4, 5]
  println y // => 4
  // println _ // [Static type checking] - The variable [_] is undeclared.
}
{code}

I was a little surprised by your example (tweaked below):

{code:groovy}
@CompileStatic
def method3() {
  def _ = 1
  def  (_, y, _) = [3, 4, 5]
  println y // => 4
  println _ // => 5
}
{code}

I think if a dynamic variable is found, we follow dynamic rules for backwards 
compatibility/less surprise of a difference from dynamic code. I'd have to 
check the test cases to refresh my memory if that was explicitly covered, or a 
bug, or intended behavior we possibly didn't specify well enough.

The use in the lambda expression does look weird. That could easily be a bug 
that might arise from some of the earlier assumptions being incorrectly applied 
in the wrong context.


was (Author: paulk):
There might be a bug there but it might not be as you expect.

We looked at a lot of usage of dynamic code Groovy where "_" can come from the 
binding (with no declaration) and usage in Jenkins builds and Spock tests. We 
decided upon leaving underscore as a dynamic variable:

https://github.com/apache/groovy/pull/1867#issuecomment-1447527890

That means the following is expected:

{code:groovy}
def method1() {
  def  (_, y, _) = [3, 4, 5]
  println _ // 5, last usage
}
{code}

It was going to break what we believed was valid existing dynamic code if we 
followed Java semantics exactly here.

With CompileStatic, they do act more like unnamed in Java. The binding doesn't 
arise in such code. If you uncomment the last line, it won't compile. That is 
expected.

{code:groovy}
@CompileStatic
def method2() {
  def  (_, y, _) = [3, 4, 5]
  println y // => 4
  // println _ // [Static type checking] - The variable [_] is undeclared.
}
{code}

I was a little surprised by your example (tweaked below):

{code:groovy}
@CompileStatic
def method3() {
  def _ = 1
  def  (_, y, _) = [3, 4, 5]
  println y // => 4
  println _ // => 5
}
{code}

I think if a dynamic variable is found, we follow dynamic rules for backwards 
compatibility/less surprise of a difference from dynamic code. I'd have to 
check the test cases to refresh my memory if that was explicitly covered, or a 
bug, or intended behavior we possibly didn't specify well enough.

> Unnamed variables are actually used
> -----------------------------------
>
>                 Key: GROOVY-11744
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11744
>             Project: Groovy
>          Issue Type: Bug
>            Reporter: Georgii Ustinov
>            Priority: Major
>
> I am currently implementing Groovy 5 support inside Intellij IDEA and 
> encountered the following behaviour. Consider the following code:
> {code:java}
> package org.example.demo
> static void main(String[] args) {
>     def _ = 1
>     def (_, _) = [2, 3]
>     println _
> } {code}
> I expected that it will print 1, since variable declaration contains only 
> unnamed variables.
> Actually it prints 3. The same behaviour can be encountered here:
> {code:java}
> def _ = 1
> def x = (_, _) -> {
> println(_)
> }
> x(2, 3){code}
> I beileve this is a bug. 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to