[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15521379#comment-15521379 ] ASF GitHub Bot commented on GROOVY-7933: Github user asfgit closed the pull request at: https://github.com/apache/groovy/pull/424 > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15494628#comment-15494628 ] Paul King commented on GROOVY-7933: --- Jochen, when you run this, do you get what you expect: {code} int a(int a) { 0 } int a(Integer a) { 1 } int val = 2 assert a(val) == 1 def x = a(val) assert x == 1 {code} > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15492946#comment-15492946 ] Jochen Theodorou commented on GROOVY-7933: -- ah... I get a feeling I know the problem this is coming from. when doing a(foo), we may be able to do a direct method call in some cases. If foo is a boolean, then there must be a a(boolean) exist to work. If we do x.a(foo), then this is in dynamic Groovy never a direct call. To relialize the method call foo will be wrapped in an Object[] at some point and the type taken for the dispatch is the one out of this array. Which means foo will be Boolean instead. For Groovy with indy, this is different. Here foo will be the primitive type. And there is also the problem of MOP methods. For example an a(foo) in a Closure. This will cause method dispatch to go through an invokeMethod somewhere, or the MetaClass system, which too takes only an Object[] and not possibly known types from the callsite. So here again a(foo) would prefer a(Boolean). Using a cast helps carrying the information over, but only to the first MetaClass. After that, the information might get lost. Not sure what way we should go to fix this. For indy there is actually nothing to fix here, if we ignore the MOP. And I am not sure it is really worth fixing it for non-indy Groovy. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15486826#comment-15486826 ] Jose Ignacio Acin Pozo commented on GROOVY-7933: Should @CompileStatic and interpreted behaviour actually be different? I think it sort of makes sense as @CompileStatic methods should be chosen at compile time(like Java does) instead of runtime (like Groovy does): >From http://groovy-lang.org/differences.html#_multi_methods : "In Groovy, the methods which will be invoked are chosen at runtime. This is called runtime dispatch or multi-methods. It means that the method will be chosen based on the types of the arguments at runtime. In Java, this is the opposite: methods are chosen at compile time, based on the declared types." >From >http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/CompileStatic.html > : "This will let the Groovy compiler use compile time checks in the style of Java then perform static compilation, thus bypassing the Groovy meta object protocol. When a class is annotated, all methods, properties, files, inner classes, etc. of the annotated class will be type checked." Also more info taken from here http://java-performance.info/static-code-compilation-groovy-2-0/ : "Static compilation allows Groovy 2.0 to generate direct method calls, which are no longer using Groovy runtime as an intermediary. This feature actually allows you to avoid going into the Groovy runtime for the huge share of methods – think how many overloaded methods do you usually have in your code – non-overloaded methods could always be safely converted into the normal method calls." > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15486048#comment-15486048 ] Henri Tremblay commented on GROOVY-7933: It think it should be fixed indeed. At least for one reason: Right now you have a different behavior between @CompileStatic and interpreted code. That doesn't make sense. On my side, the issue would currently force me to add an overload dedicated to Groovy. Normally, in Java we need `foo(boolean)` and `foo(Object)`. This would also for me to add a `foo(Boolean)` to please Groovy. It seems sad for interoperability. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485466#comment-15485466 ] Jose Ignacio Acin Pozo commented on GROOVY-7933: Of course, your resolution makes more sense. I was not taking into account the widening possibility, just the boxed/unboxed possibilities for an Integer. I think you meant: {code} class Demo { String a(int i) { 'int' } String a(Integer bigI) { 'Integer' } void test() { String result = a(42) // 'int' instead of 'Integer' assert result == 'int' } static void main(args) { String result = new Demo().a(42) assert result == 'Integer' new Demo().test() } } {code} This behaviour is way too confusing and I wonder how it went unnoticed for so many years, or if there was a real reason indeed for doing it this way and it is just not documented/explained properly. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485443#comment-15485443 ] John Wagenleitner commented on GROOVY-7933: --- {quote}Primitives like Integer should be something like: a(Integer) > a(int) > a(Number) > a(Object). In summary: Unboxed > Boxed > More concrete subclass or implementation (if any) > Object. Am I correct?{quote} For Integer I believe the resolution is: {{Integer > int > long > Long > BigInteger > float > Float > double > Double > BigDecimal > Number > Object}} However, there seems to be a difference between which of the first 2 are resolved (Integer vs int) depending on where the call originates. For example, if you run the following it will fail in the {{test()}} instance method (sender/receiver are the same): {code} class Demo { String a(int i) { 'int' } String a(Integer bigI) { 'Integer' } void test() { String result = a(42) assert result == 'Integer' } static void main(args) { String result = new Demo().a(42) assert result == 'Integer' new Demo().test() } } {code} Sorry, getting a little off-topic for this particular reported issue, but this doesn't seem right to me. This is not just the case for Integer but also for the other boxed primitive types. It looks like GROOVY-7850 has noted this inconsistency as well. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485343#comment-15485343 ] John Wagenleitner commented on GROOVY-7933: --- If the methods are called in the same class it works, it's only when the sender/receiver are different. So a script like this works: {code} String a(boolean b) { 'boolean' } String a(Object o) { 'Object' } String result = a(true) assert result == 'boolean' {code} and one like this fails: {code} class Foo { String a(boolean b) { 'boolean' } String a(Object o) { 'Object' } } String result = new Foo().a(true) assert result == 'boolean' {code} > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485289#comment-15485289 ] Jose Ignacio Acin Pozo commented on GROOVY-7933: Fair enough. I always went my way by doing defensive coding to avoid these situations, so seeing now that there are two exceptions for "boolean" and "char" while the rest work correctly feels very confusing. I also think this should be documented somewhere very clearly, as the mantra "Groovy uses Objects for everything" is pretty much everywhere in documentation, with special mentions when talking about method resolution and primitives autowrapping. If this behaviour is changed to satisfy "boolean" and "char" primitives as well, then, the method resolution should be something like this: a(Boolean) > a(boolean) > a(Object). Primitives like Integer should be something like: a(Integer) > a(int) > a(Number) > a(Object). In summary: Unboxed > Boxed > More concrete subclass or implementation (if any) > Object. Am I correct? > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485229#comment-15485229 ] John Wagenleitner commented on GROOVY-7933: --- It seems to work as expected for all primitives except for {{boolean}} and {{char}}. Looks like those primitive types are not taken into account when calculating the method parameter distances which is causing the method taking an {{Object}} to be selected first. https://github.com/apache/groovy/blob/53b99ebb460ae26fd8483bc894cc3703cd7af48f/src/main/org/codehaus/groovy/runtime/MetaClassHelper.java#L206-L231 Both {{boolean}} and {{char}} do not seem to be eligible for conversion to other types which may explain why they are missing from the distance table. But perhaps they should be added and have a distance to the other types set to -1 except for their associated wrapper class and Object or maybe handled specially in the {{getPrimitiveDistance(Class from, Class to)}} method so as not to complicate the distance tables. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485196#comment-15485196 ] John Wagenleitner commented on GROOVY-7933: --- I think the issue here is that in the absence of a method taking Boolean, the call should be unboxed and the {{boolean}} method called over the one taking {{Object}}. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15485152#comment-15485152 ] Jose Ignacio Acin Pozo commented on GROOVY-7933: That would be the expected method resolution. In Java. Groovy documentation says otherwise, as the method resolution works in different way, because primitives are autowrapped: http://docs.groovy-lang.org/latest/html/documentation/core-object-orientation.html#_primitive_types http://docs.groovy-lang.org/latest/html/documentation/core-differences-java.html#_primitives_and_wrappers So in Groovy the order for calling "a(true)" should be something like: a(Boolean), a(Object) and last but not least a(boolean). You can test this behaviour by extending the code: public class Demo { public String a(boolean a) { 'boolean was called' } public String a(Object a) { 'Object was called' } public String a(Boolean a) { 'Boolean was called' } static void main(args) { assert new Demo().a((boolean)true) == 'boolean was called' //pass assert new Demo().a(true) == 'Boolean was called' //fail } } I am happy to be corrected, but I have used Groovy for a long time, and learned this the hard way. If this is actually a bug, then the documentation is very wrong. > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15484673#comment-15484673 ] Henri Tremblay commented on GROOVY-7933: Great. Thanks [~jwagenleitner]. Do you confirm this is not the intended behavior? > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)
[jira] [Commented] (GROOVY-7933) Incorrect boxing of boolean primitive types
[ https://issues.apache.org/jira/browse/GROOVY-7933?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=15483838#comment-15483838 ] Jochen Theodorou commented on GROOVY-7933: -- I am not able to reproduce this > Incorrect boxing of boolean primitive types > --- > > Key: GROOVY-7933 > URL: https://issues.apache.org/jira/browse/GROOVY-7933 > Project: Groovy > Issue Type: Bug > Components: groovy-runtime >Affects Versions: 2.4.7 >Reporter: Henri Tremblay > > A boolean primitive type seems to be boxed for no apparent reason. See the > example below. The problem disappear when using @CompileStatic or if > explicitly casting to (boolean). > {code:java} > public class Demo { >public void a(boolean a){ >System.out.println("boolean was called"); >} >public void a(Object a){ >System.out.println("Object was called"); >} > } > class Groovy { >static void main(String[] args) { >def demo = new Demo() >demo.a(true) >} > } > {code} > *Output:* > Object was called -- This message was sent by Atlassian JIRA (v6.3.4#6332)