groovy icon indicating copy to clipboard operation
groovy copied to clipboard

GROOVY-10682: Provide eachWithIndex for primitive arrays

Open Shadow-Devil opened this issue 2 years ago • 2 comments

Consider the following:

@groovy.transform.TypeChecked
void test(int[] ints) {
  ints.eachWithIndex { value, index ->
    println "$index: ${value.doubleValue()}"
  }
}
test(0,1,2,3,4,5)
Compiler reports "[Static type checking] - Cannot find matching method java.lang.Object#doubleValue()"

eachWithIndex is only provided for reference types, so "value" is seen as Object by the type checker.

Currently, only a draft for int arrays. Should probably also be implemented for other primitive types. There are three different approaches to do this:

  1. Copy-paste the implementation for each overload
  2. Delegate to eachWithIndex(Iterable<T> self, Closure closure)
  3. Delegate to eachWithIndex(Iterator<T> self, Closure closure)

I found option three most appealing since option 1 adds unnecessary code duplication and option 2 just calls option 3 with the iterator of self which would add unnecessary overhead.

https://issues.apache.org/jira/browse/GROOVY-10682

Shadow-Devil avatar Sep 21 '22 14:09 Shadow-Devil

This is a good start. I added some notes on the commit. You should compare to the javadoc for the T[] variant and try to match it, except here you know the array element type so you may be able to make some small improvements.

eric-milles avatar Sep 21 '22 15:09 eric-milles

If we're adding eachWithIndex it appears we also need each to satisfy STC. Can you add an each(int[]) as well?

eric-milles avatar Sep 21 '22 15:09 eric-milles

If we're adding eachWithIndex it appears we also need each to satisfy STC. Can you add an each(int[]) as well?

The reason I did not pick this ticket up after creating it is there was no reasonable stopping point. If adding eachWithIndex, what about each, reverseEach, every and all the other T[] extensions. I wonder if there is some way to write just one implementation and have all the primitive versions be generated automatically. @paulk-asert Do you know of such a thing? Or should we consider the possibility of allowing the T[] or Object[] apply to primitive arrays as well through Groovy "auto-unboxing"?

eric-milles avatar Sep 22 '22 14:09 eric-milles

We have used code generators (hand-hacked throwaway Groovy scripts) from time to time to generate repeated patterns.

We could enhance both the dynamic and static behaviours to do some kind of array-level "auto-unboxing" for T[] and the like but we have opted not to in the past for better Java integration and (at the time) efficiency with the hand-coded primitive variants likely to be more efficient.

We also have IntArrayIterable (and Long/Double variants). So we could write:

public static int[] eachWithIndex(int[] self, @ClosureParams(value=FromString.class, options="Integer,Integer") Closure closure) {
    eachWithIndex(new IntArrayIterable(self), closure);
    return self;
}

This saves work when writing the new variants but is probably slightly less efficient that the current code in this PR. This is option 2 in the original proposal but I am not sure whether IntArrayIterable was part of the original plan. It will be more efficient than falling-through via other means.

paulk-asert avatar Sep 22 '22 22:09 paulk-asert

:warning: 170 God Classes were detected by Lift in this project. Visit the Lift web console for more details.

sonatype-lift[bot] avatar Sep 26 '22 17:09 sonatype-lift[bot]

@sonatype-lift ignore

paulk-asert avatar Oct 04 '22 17:10 paulk-asert

I'm trying to fight through the sonatype comments. But it is looking ready for review to me.

eric-milles avatar Oct 10 '22 17:10 eric-milles

Could someone please approve the workflow?

Shadow-Devil avatar Oct 13 '22 17:10 Shadow-Devil

LGTM

paulk-asert avatar Oct 18 '22 10:10 paulk-asert

Merged, thanks! I might make some minor formatting changes post merge. I am also thinking have the TypeChecked annotation in the groovyTestCase tests in javadoc probably adds noise that doesn't need to be there. I'll ponder whether we should tweak that somehow.

paulk-asert avatar Oct 18 '22 10:10 paulk-asert