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

Paul King commented on GROOVY-10666:
------------------------------------

Yes, the example I gave was contrived. We have traditionally split what getAt 
and iterator do in terms of behavior and you could make incongruent examples - 
but they would perhaps already have been surprising. It still makes me wonder 
though if there is an improvement possible to implement what I agree would 
certainly be a useful feature.

What about we add a DGM#getAtAll method:

public static Tuple getAtAll(Object self) {
    return new Tuple(toList(iterator(self)).toArray());
}

But instead of an eager Tuple, return a lazy tuple which could be backed by an 
iterator or loop with getAt - we could do metaclass level checking perhaps. But 
the point being it takes the multiple paths out of the generated bytecode.

Then in the bytecode, call getAtAll storing in a temp variable then looping 
through with code similar to now but instead of getAt on the object, get on the 
tuple.

That also leaves open for classes to implement their own getAtAll returning a 
typed TupleN?

Do you see any gaping holes at least in principle?

> Implement multiple-assignment (aka destructuring) via getAt(IntRange) or 
> iterator()
> -----------------------------------------------------------------------------------
>
>                 Key: GROOVY-10666
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10666
>             Project: Groovy
>          Issue Type: Improvement
>          Components: bytecode, groovy-jdk
>            Reporter: Eric Milles
>            Assignee: Eric Milles
>            Priority: Minor
>
> Currently multiple-assignment is implemented using {{getAt(int)}}.  For types 
> that support {{getAt(IntRange)}} it may be more efficient to use that 
> operation.  For cases where {{getAt(int)}} is a terminal operation (aka 
> streams) it may be the only way to go.  Or maybe using one {{iterator()}} 
> would be better overall.
> Consider the following:
> {code:groovy}
> Set<String> set = ['foo','bar','baz']
> def (foo, bar, baz) = set // inefficient; requires 3 iterators and 6 calls to 
> next
> Stream<String> stream = ['foo','bar','baz'].stream()
> def (foo, bar, baz) = stream // not possible because `getAt(int)` is terminal
> {code}



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

Reply via email to