[
https://issues.apache.org/jira/browse/GROOVY-12442?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18131642#comment-18131642
]
ASF GitHub Bot commented on GROOVY-12442:
-----------------------------------------
testlens-app[bot] commented on PR #2996:
URL: https://github.com/apache/groovy/pull/2996#issuecomment-6392064488
## 🚨 TestLens detected 1 failed test 🚨
### Test Summary
> [!TIP]
> Inspect all details with the [TestLens
CLI](https://testlens.app/docs/features/cli): `testlens pr 2996`
#### [Build and test / lts \(17,
ubuntu-latest\)](https://github.com/apache/groovy/actions/runs/40150814234/job/121041821771?pr=2996)
> :groovy-lsp:test
| Test | Runs | Flakiness |
|---|---|--:|
| GroovyLanguageServerTest >
publishDiagnosticsIncludeVersionAndClearRemovedUris\(\) | ❌ | 1% 🟡 |
🏷️ Commit: 74d5d14303147994347756ca53a53525eca16b32
▶️ Tests: 28644 executed
🟡 Checks: 6/30 completed
### Test Failures
<details><summary><strong>GroovyLanguageServerTest >
publishDiagnosticsIncludeVersionAndClearRemovedUris()</strong>
(:groovy-lsp:test in <a
href="https://github.com/apache/groovy/actions/runs/40150814234/job/121041821771?pr=2996">Build
and test / lts (17, ubuntu-latest)</a>)</summary>
```
java.util.ConcurrentModificationException
at
java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getPropertySpreadSafe(ScriptBytecodeAdapter.java:503)
at
org.apache.groovy.lsp.GroovyLanguageServerTest.publishDiagnosticsIncludeVersionAndClearRemovedUris(GroovyLanguageServerTest.groovy:253)
```
</details>
### Rerun Controls
> [!NOTE]
> Checks are currently running using the configuration below.
Select tests to mute in this pull request:
🔲 GroovyLanguageServerTest >
publishDiagnosticsIncludeVersionAndClearRemovedUris\(\) <!
> Introduce a null-coalescing operator (??) that provides a default value only
> when the left-hand operand is null, independently of Groovy Truth.
> -----------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12442
> URL: https://issues.apache.org/jira/browse/GROOVY-12442
> Project: Groovy
> Issue Type: New Feature
> Components: syntax
> Reporter: Jefferson H
> Priority: Minor
>
> h2. Motivation
> Groovy currently provides the Elvis operator ({{{}?:{}}}) for default values.
> However, its behavior relies on Groovy Truth, which treats values such as
> {{{}0{}}}, {{{}false{}}}, empty strings, and empty collections as false.
> This behavior is useful in many situations, but it can also lead to
> unexpected results when those values are intentional and valid.
> *For example:*
>
> {code:java}
> def retries = 0
> def result = retries ?: 3
> assert result == 3 {code}
>
> In this case, {{0}} is a valid configuration value representing no retries,
> but the Elvis operator replaces it with {{{}3{}}}.
> Currently, developers must use an explicit null check:
>
> {code:java}
> def result = retries != null ? retries : 3 {code}
>
> This introduces unnecessary verbosity for a common use case.
> h2. Proposed Syntax
> Introduce the {{??}} operator:
>
> {code:java}
> def result = value ?? defaultValue {code}
>
> The right-hand expression should be evaluated only when the left-hand
> expression evaluates to {{{}null{}}}.
> h2. Expected Behavior
>
> {code:java}
> assert (null ?? 10) == 10
> assert (0 ?? 10) == 0
> assert (false ?? true) == false
> assert ('' ?? 'default') == ''
> assert ([] ?? [1, 2]) == []
> assert ([:] ?? [enabled: true]) == [:] {code}
> Short-circuit evaluation
>
> The left operand should be evaluated exactly once, and the right operand
> should only be evaluated when necessary.
> {code:java}
> def calls = 0
> def fallback = {
> calls++
> return 10
> }
> assert (0 ?? fallback()) == 0
> assert calls == 0
> assert (null ?? fallback()) == 10
> assert calls == 1
> {code}
> h2. Comparison with Existing Elvis Operator
> ||Value||{{value ?: default}}||{{value ?? default}}||
> |{{null}}|default|default|
> |{{0}}|default|{{0}}|
> |{{false}}|default|{{false}}|
> |{{''}}|default|{{''}}|
> |{{[]}}|default|{{[]}}|
> |Non-empty value|original|original|
> h2. Benefits
> * Provides explicit null-only fallback semantics.
> * Preserves valid falsy values without additional conditional expressions.
> * Improves readability and reduces boilerplate.
> * Complements the existing Elvis operator rather than replacing it.
> * Aligns Groovy with familiar null-coalescing syntax found in languages such
> as C#, JavaScript, and PHP.
> * Helps avoid subtle configuration bugs involving counters, flags, and empty
> values.
> h2. Compatibility Considerations
> This proposal does not require changing the existing behavior of Groovy
> Truth, {{{}?:{}}}, or {{{}?={}}}.
> The new operator should work with dynamically typed and statically compiled
> Groovy code.
> Operator precedence, associativity, interaction with other conditional
> operators, and parser compatibility would need to be defined as part of the
> implementation.
> h2. Optional Future Enhancement
> A null-coalescing assignment operator ({{{}??={}}}) could be considered
> separately:
> {code:java}
> def retries = 0
> retries ??= 3
> assert retries == 0 {code}
> The initial proposal focuses only on the {{??}} operator.
> h2. Acceptance Criteria
> * {{??}} returns the left-hand value whenever it is not {{{}null{}}}.
> * {{??}} returns the right-hand value when the left-hand value is
> {{{}null{}}}.
> * The left-hand expression is evaluated exactly once.
> * The right-hand expression is evaluated lazily.
> * Falsy non-null values are preserved.
> * Existing Elvis operator behavior remains unchanged.
> * The operator is supported by the Groovy parser and static compilation.
> * Tests and language documentation are added.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)