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

Reply via email to