On 01/05/2019 20:34, Brian Goetz wrote:
ne big difference between whether we convert V to V? via subsumption
or via a boxing conversion is how overload selection is done. But, if
we have methods m(Object) and m(V?), and it is invoked with a v, in
the subtyping case, we'll select m(Object), and in the conversion
case, we'll select m(V?). But it's not clear that this is what we want
There's a tiny gap in this line of reasoning.
All these arguments rely on the fact that V <: Object, I realized.
While, again, this might be true from a VM perspective, it doesn't have
to be true for the language. We can be in a world where:
V? <: Object
and
V ~> V?
That is, the first relation is covered by subtyping, while the latter
involves a conversion (albeit a trivial one).
If you go down this path, overload resolution works the way you expect:
if you wanna pass a V to a m(Object) or m(V?) you require a conversion
anyway. So m(V?) wins because it's most specific.
If you wanna pass a V to m(V) or m(V?), m(V) wins, and m(V?) wouldn't
even be considered.
All this boils down, I think, to one question: do we want array
covariance? E.g. should
V[] <: Object[]
?
If yes, then we need to have V <: Object (which then implies also V <:
V?). If not, then we can use conversions as described above.
Another factor that might inform the decision is wildcard treatment (as
covariance is unsurprisingly related to arrays) - do we want:
List<? extends V> <: List<? extends Object> ?
These are, IMHO, they key questions - once we answer them unambiguously,
all else fall as a sequence of basically forced moves, I think.
P.S.
If we're really appealing to int vs. long, as John noted, int[] and
long[] are unrelated types currently, so as int[] and Object[], which
seems to push against covariance. I also remember some arguments
exchanged about subtyping between primitive types being a 'bug' in the
current JLS - e.g. int <: long is more a bug than a feature, but I could
be remembering incorrectly.
Maurizio