[ 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)