Yay cross-posting. I include the content of my post to jvm-l here for compiler-dev to muse upon:
On Thu, Jun 9, 2011 at 1:11 PM, Attila Szegedi <szege...@gmail.com> wrote: > The question however is whether these solutions we perceive as intuitive can > indeed be formally valid under some set of consistent rules, without running > into a contradiction. In answer to you and Neal, it seems there's a simple way to improve the spec to provide the "intuitive" result (or at least the result most people here seem to find intuitive: treat primitives as more specific than Object (and potentially over boxed numeric types as well). My (mis)interpretation of the Java spec for Mirah's compiler works this way currently; primitives are given priority over reference types unconditionally, since the alternative *requires* a boxing conversion. If you have to walk through a conversion to get there, you're walking into a less-specific signature. Walking back through phase 3 and specificity (and I apologize for the informality of this..I'm not a spec writer): Given: void foo(String, int, Object...) void foo(String, Object...) foo("bar", 1) or foo("bar", 1, "baz") * phase three is selected because only varargs can apply * the second signature is only valid for the given arguments with a method invocation conversion of int => Integer * Integer is a subclass of Object, so we arrive at the ambiguity from before * ...BUT...primitive is always more specific than reference, and so the int method is chosen I know many folks hate the special treatment of primitives in Java, but this sort of exception is nothing new. Yes, primitives and reference types live in different worlds and do not share a hierarchy. I would argue that their disjointedness explicitly makes the strict subtype specificity check invalid; subtyping has no meaning to primitives, so you're measuring specificity of an int parameter with an invalid metric. It would be like measuring the specificity of Integer versus Long based on their bit sizes and bit-level widening conversions. Since that doesn't make sense, neither does forcing subtype-driven specificity constraints on primitive types. - Charlie On Thu, Jun 9, 2011 at 2:07 PM, Dan Smith <daniel.sm...@oracle.com> wrote: > On Jun 9, 2011, at 10:17 AM, Ulf Zibis wrote: > >> Am 09.06.2011 17:26, schrieb Rémi Forax: >>> On 06/09/2011 04:52 PM, Robert Fischer wrote: >>>> I've been using precisely the pattern that Charlie lays out in some of my >>>> code, as well, so I'm going to have to code around it now. I didn't >>>> realize that it was technically ambiguous — it's really surprising to my >>>> intuition, which (I'm now realizing as I think about it) tries to match >>>> arguments left to right, and only drops to varargs if it can't find a >>>> match. That intuition is obviously wrong compared to the spec, but does >>>> that mean we have a bug in the spec? What's the justification for this >>>> behavior? >>>> >>>> For the record, both Scala and Groovy resolve methods more in line with >>>> intuition: >>>> Groovy > https://gist.github.com/1016878 >>>> Scala > https://gist.github.com/1016880 >>>> >>> >>> Yes, because either in Scala or in Groovy int is a subtype of Object. >>> There is no point to make a difference between int and Integer in a dynamic >>> language. >> >> I think, C++ would be the more appropriate language to compare here. Does >> anybody here know, how C++ would solve this problem? >> >> what's about: >> method("str", new Integer(1)); >> Because Integer can be unboxed to int, there should be an ambiguity too >> according given rules, which feels more weird to me. >> >> The only cases, which are not ambiguous here, seem to be: >> method("str", true); >> method("str", 1.0); >> method("str", 1L); >> So allowing the coexistence of those 2 signatures would seem weird too. >> >> IMO, not (un)boxed matches should be valued as "more specific"! > > "more specific" is a relation among method signatures, so it would not be > easy to adjust its definition in this way. > > The process has two steps: 1) find applicable methods, using the argument > types; 2) choose the most specific method, ignoring the argument types. > Seems like the right way to express what you're after within the current > framework is to have a fourth applicability phase: > > 1) Applicable by subtyping > 2) Applicable by method invocation > *3) Applicable by subtyping with varargs* > 4) Applicable by method invocation with varargs > > This would also address the original concern, although I think people might > debate whether it's the correct behavior for: > > void method(String s, int n, Object... os); > void method(String s, Object... os); > method("abc", new Integer(3)); > > —Dan > > -- You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to jvm-languages@googlegroups.com. To unsubscribe from this group, send email to jvm-languages+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en.