[
https://issues.apache.org/jira/browse/GROOVY-11964?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18076348#comment-18076348
]
ASF GitHub Bot commented on GROOVY-11964:
-----------------------------------------
paulk-asert commented on code in PR #2489:
URL: https://github.com/apache/groovy/pull/2489#discussion_r3143674343
##########
src/test/groovy/gls/statements/MultipleAssignmentDeclarationTest.groovy:
##########
@@ -226,4 +226,1326 @@ final class MultipleAssignmentDeclarationTest {
assert baz == 'baz'
'''
}
+
+ // GEP-20 tail-rest tests
+
+ @Test
+ void testTailRestFromList() {
+ assertScript '''
+ def (h, *t) = [1, 2, 3, 4]
+ assert h == 1
+ assert t == [2, 3, 4]
+ '''
+ }
+
+ @Test
+ void testTailRestWithMultipleHeads() {
+ assertScript '''
+ def (a, b, *rest) = [10, 20, 30, 40, 50]
+ assert a == 10
+ assert b == 20
+ assert rest == [30, 40, 50]
+ '''
+ }
+
+ @Test
+ void testTailRestWithTypedHead() {
+ assertScript '''
+ def (int h, *t) = [1, 2, 3]
+ assert h == 1
+ assert h instanceof Integer
+ assert t == [2, 3]
+ '''
+ }
+
+ @Test
+ void testTailRestFromEmptyList() {
+ assertScript '''
+ def (h, *t) = []
+ assert h == null
+ assert t == []
+ '''
+ }
+
+ @Test
+ void testTailRestFromString() {
+ assertScript '''
+ def (c, *cs) = "hello"
+ assert c == 'h'
+ assert cs == "ello"
+ '''
+ }
+
+ @Test
+ void testTailRestFromIterator() {
+ assertScript '''
+ def (h, t) = [1, 2, 3].iterator() // baseline: same iterator
semantics as existing
+ assert h == 1
+ assert t == 2
+
+ // tail-rest binds the advanced iterator (Path B)
+ def it = [10, 20, 30].iterator()
+ def (head, *tail) = it
+ assert head == 10
+ assert tail instanceof Iterator
+ assert tail.next() == 20
+ assert tail.next() == 30
+ assert !tail.hasNext()
+ '''
+ }
+
+ @Test
+ void testTailRestFromSet() {
+ assertScript '''
+ def s = new LinkedHashSet<>([7, 8, 9])
+ def (sh, *st) = s
+ assert sh == 7
+ def remaining = []
+ while (st.hasNext()) remaining << st.next()
+ assert remaining == [8, 9]
+ '''
+ }
+
+ @Test
+ void testTailRestFromStream() {
+ assertScript '''import java.util.stream.Stream
+ def (first, *rest) = Stream.of('a', 'b', 'c')
+ assert first == 'a'
+ assert rest instanceof Iterator
Review Comment:
These work if that is what you are getting at:
```
def (hs, *ts) = Stream.iterate(0, n -> n + 2)
assert hs == 0 && ts.limit(4).toList() == [2, 4, 6, 8]
def (hi, *ti) = Iterators.iterate(0, n -> n + 2)
assert hi == 0 && ti.take(4).toList() == [2, 4, 6, 8]
```
> Additional multi-assignment forms
> ---------------------------------
>
> Key: GROOVY-11964
> URL: https://issues.apache.org/jira/browse/GROOVY-11964
> Project: Groovy
> Issue Type: Improvement
> Reporter: Paul King
> Priority: Major
>
> Three idioms are common in modern languages but unavailable in Groovy:
> * Tail rest binding: {{def (h, *t) = list}} - separate the head from the
> remainder. Common in functional code (recursive list traversal,
> pipeline-style processing of streams and iterators).
> * Map-style destructuring: {{def (name: n, age: a) = person}} - extract named
> properties or map keys directly, without intermediate variables.
> * Rest in non-tail positions: {{def (*f, last) = list, def (l, *m, r) =
> list}} - useful when the boundaries are at the ends rather than the middle.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)