[ https://issues.apache.org/jira/browse/GROOVY-10535?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17531849#comment-17531849 ]
Jochen Theodorou commented on GROOVY-10535: ------------------------------------------- [~emilles]The line https://github.com/apache/groovy/blob/6b6a3e8a6fec2826f13cc0e6a52dcf1f25b4d74b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java#L930 should add the test for the null case, 945 then builds it together. It really is just a null check there and if it succeeds it will continue with "handle", if not it will continue with "fallback". fallback is the general/slow path, that should also reset the callsite. So what if it was not null and becomes null. SAME_CLASS simply calls https://github.com/apache/groovy/blob/6b6a3e8a6fec2826f13cc0e6a52dcf1f25b4d74b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java#L196 {code:java} if (o == null) return false; return o.getClass() == c; {code} You then have the null check here instead of a special null-check-methodhandle. Of course this could be expressed with more method handles (maybe not the ==, but I am not sure). So for example the code in theory could be simplified by using the null-guard always and have the class equality check on it own. Maybe in case it is not clear.... image a guardWithTest as a composition of 3 handles, on condition handle, one true-case handle and one handle for the false-case. All of them operate on the given arguments. condition must fit the input arguments and return boolean, true and false cases must have a signature fitting to required input and output. You can very well have the true/false cases as guards as well, allowing you to build a tree structure - a bit like a decision tree. For Groovy it is more like a list, where the false-case is the slow path and the true-case is whatever we want to test further or execute. > IF condition on empty Collection has different behavior than null Collection > ---------------------------------------------------------------------------- > > Key: GROOVY-10535 > URL: https://issues.apache.org/jira/browse/GROOVY-10535 > Project: Groovy > Issue Type: Bug > Affects Versions: 3.0.10 > Environment: Groovy 3.0.10/OpenJDK 17.0.2 - Ubuntu 21.10 > Reporter: Rodolfo Yanke > Assignee: Eric Milles > Priority: Major > Fix For: 5.0.0-alpha-1, 3.0.11, 4.0.3 > > > I believe this code should print "something" but doesn't work: > {code:java} > @CompileStatic > class NotWorkingExample { > static void main(String[] args) { > Collection<String> values = null > for (i in 0..<200_000) { > printSomethingIfNotEmpty(values) > } > //never printed but it should > values = ['A'] > printSomethingIfNotEmpty(values) > } > static printSomethingIfNotEmpty(Collection<String> values) { > if(values) { > println 'something' > } > } > } > {code} > This one does print "something" because we pass an empty collection [] > instead of null: > {code:java} > @CompileStatic > class ItWorks { > static void main(String[] args) { > Collection<String> values = [] > for (i in 0..<200_000) { > printSomethingIfNotEmpty(values) > } > //it works because [] was passed in the previous 200k calls > values = ['A'] > printSomethingIfNotEmpty(values) > } > static printSomethingIfNotEmpty(Collection<String> values) { > if(values) { > println 'something' > } > } > }{code} > Some optimization is done differently when the condition is skipped too many > times. Both classes should output "something" on the last method call. > Thank you for the support. -- This message was sent by Atlassian Jira (v8.20.7#820007)