Paul King created GROOVY-12218:
----------------------------------

             Summary: Complete fat-free (functional-interface) twins for the 
array (`T[]`) forms of the GROOVY-12054 DGM methods
                 Key: GROOVY-12218
                 URL: https://issues.apache.org/jira/browse/GROOVY-12218
             Project: Groovy
          Issue Type: Sub-task
            Reporter: Paul King


h3. Summary

GROOVY-12054 added {{java.util.function}} twins beside the Closure overloads of 
the core higher-order DGM methods, but only in {{DefaultGroovyMethods}} — the 
array-receiver forms in {{ArrayGroovyMethods}} were left with only their 
{{Closure}} overloads. This completes the object-array ({{T[]}}) twins so array 
receivers reach parity with the collection receivers. Each twin simply 
delegates to the corresponding DGM {{Iterable}}/{{Iterator}} twin (already 
shipped in GROOVY-12054) via {{ArrayIterable}}/{{ArrayIterator}}, following the 
array pattern established in GROOVY-12215 / GROOVY-12216.

Already covered (not in scope): {{each}} on primitive arrays already has 
{{Consumer}}/{{IntConsumer}}/etc. twins; {{collectEntries}} already has the 
two-{{Function}} {{(keyTransform, valueTransform)}} forms; and the array forms 
of 
{{groupBy}}/{{collectMany}}/{{countBy}}/{{split}}/{{takeWhile}}/{{dropWhile}} 
(GROOVY-12215) and {{inject}}/{{injectAll}} (GROOVY-12216) are done.

h3. Object-array twins to add

||Method (array form)||Count||Functional type||
|{{each(T[])}}|1|{{Consumer<? super T>}}|
|{{eachWithIndex(T[])}}|1|{{ObjIntConsumer<? super T>}}|
|{{collect(T[])}}, {{collect(T[], Collection collector)}}|2|{{Function<? super 
E, ? extends T>}}|
|{{collectEntries(T[])}}, {{collectEntries(T[], Map collector)}}|2|{{Function<? 
super E, ? extends Map.Entry<K, V>>}}|
|{{any(T[])}}|1|{{Predicate<? super T>}}|
|{{every(T[])}}|1|{{Predicate<? super T>}}|
|{{find(T[])}}|1|{{Predicate<? super T>}}|
|{{findAll(T[])}}|1|{{Predicate<? super T>}}|
|{{count(T[])}}|1|{{Predicate<? super T>}}|

Total: 11 object-array twins.

h3. Primitive-array predicates (decision needed)

{{any}}/{{every}}/{{count}} on primitive arrays currently take only a 
{{Closure}}. The JDK provides 
{{IntPredicate}}/{{LongPredicate}}/{{DoublePredicate}} but no 
{{Byte}}/{{Char}}/{{Short}}/{{Float}} predicate, so only 
{{int[]}}/{{long[]}}/{{double[]}} can be covered cleanly (3 receivers x 3 
methods = 9 twins); the other four primitive types would be inconsistent 
(widening to {{IntPredicate}} is ugly). *Options:* (a) add the 9 well-supported 
primitive twins; (b) skip primitives for predicates and cover only {{T[]}}. 
Recommendation: match how {{each}}'s primitive twins already exist only where a 
JDK SAM fits — i.e. option (a) if primitive predicate ergonomics are wanted, 
else (b).

h3. Exclusions

* {{eachWithIndex}} on primitive arrays — no JDK {{(primitive, int)}} SAM, so 
only the {{T[]}} form ({{ObjIntConsumer}}) is clean.
* The {{@Incubating}} right-curry {{(BiXxx, param)}} array forms — GROOVY-12054 
added these for {{Iterable}}/{{Iterator}} but not arrays; deferred as a 
separate item.

h3. Conventions (per GROOVY-12054)

PECS wildcards; {{@since 6.0.0}}; javadoc {{<pre class="language-groovy 
groovyTestCase">}} example cross-linking the {{Closure}} counterpart via 
{{@link}}; plain SAM overloads (not {{@Incubating}}); bodies delegate to the 
existing DGM twins.

h3. Compatibility

Existing closure/lambda call sites are unaffected; method references and typed 
functional values select the new twins under {{@CompileStatic}} (GROOVY-12214). 
The only check is an existing {{@CompileStatic}} call passing a literal 
{{null}} to a currently-single-overload array method — rare and grep-checkable, 
resolved with a cast if found.




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

Reply via email to