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

Eric Milles edited comment on GROOVY-7934 at 11/6/23 4:57 PM:
--------------------------------------------------------------

At best, we can say that "T" in variant one and "E" in variant two is the 
second parameter's type.  And we should be able to say that "V" -- the 
closure's return value -- is the first parameter type if we dropped the initial 
value business or made sure it was of type "V".

One breaking-change option is:
{code:java}
public static <T, V> V inject(Collection<T> self,
  @ClosureParams(value=FromString,options="? super V,T") Closure<V> closure) {
    return inject(self, null, closure); // Java's reduce does this
}
public static <T, U extends V, V> V inject(Collection<T> self, U initialValue,
  @ClosureParams(value=FromString,options="? super V,T") Closure<V> closure) {
    V value = initialValue;
    Object[] params = new Object[2];
    for (T item : self) {
        params[0] = value;
        params[1] = item;
        value = closure.call(params);
    }
    return value;
}
{code}

The "? super T" may be wishful thinking -- STC may not be able to handle this 
just yet. 
 This proposal is semantically different from the specification of the 
no-initial-value variant.  So it likely needs to have a new name, like 
{{foldLeft}} or {{reduce}} or whatever 
 [~paulk] Thoughts?


was (Author: emilles):
At best, we can say that "T" in variant one and "E" in variant two is the 
second parameter's type.  And we should be able to say that "V" -- the 
closure's return value -- is the first parameter type if we dropped the initial 
value business or made sure it was of type "V".

One breaking-change option is:
{code:java}
public static <T, V> V inject(Collection<T> self,
  @ClosureParams(value=FromString,options="? super V,T") Closure<V> closure) {
    return inject(self, null, closure); // Java's reduce does this
}
public static <T, U extends V, V> V inject(Collection<T> self, U initialValue,
  @ClosureParams(value=FromString,options="? super V,T") Closure<V> closure) {
    V value = initialValue;
    Object[] params = new Object[2];
    for (item : self) {
        params[0] = value;
        params[1] = item;
        value = closure.call(params);
    }
    return value;
}
{code}

The "? super T" may be wishful thinking -- STC may not be able to handle this 
just yet. 
 This proposal is semantically different from the specification of the 
no-initial-value variant.  So it likely needs to have a new name, like 
{{foldLeft}} or {{reduce}} or whatever 
 [~paulk] Thoughts?

> Type inference breaks for Collection.inject
> -------------------------------------------
>
>                 Key: GROOVY-7934
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7934
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.4.6
>            Reporter: Oliver Holp
>            Priority: Minor
>              Labels: CompileStatic
>
> The code below should not compile as the first parameter to the inject method 
> must be a string, but the integer 0 is handed in:
> {code:groovy}
> @CompileStatic
> public static void main(String[] args) {
>     def inList = ["a", "b", "c"]
>     def outList = inList.inject(0, { a, b -> a + "," + b })
>     println(outList)
> }
> {code}
> I opened this issue as adviced in the reply to the same issue I asked on 
> stackoverflow: 
> http://stackoverflow.com/questions/39444838/chance-for-this-hole-in-groovy-staic-typing-to-be-fixed/39446458#39446458



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

Reply via email to