Idea how to implement VT/VO compatibility in JVM

Vitaly Davidovich vitalyd at gmail.com
Thu Jan 22 19:59:21 UTC 2015


>
> I disagree on that point, in Java, subtyping is defined on object types
> not on primitive types,
> this is why by example the following code doesn't compile even if it's
> technically possible to change
> the way bridges are generated in order to compile it.
>
> class A {
>   double foo() { ... }
> }
> class B extends A {
>   int foo() { ... }
> }
>
> The Liskov principle is defined on objects not on primitive, we have the
> same limitation in Java.
>
> While I agree that Java is the last language with a strong separation
> between primitive types and object types. It's how Java was defined, so I
> don't think it will surprise anyone if there is not subtyping relationship
> between List<?> and List<int>.
>

The issue at hand (in this thread) is about iterating over opaque lists (or
any iterable, for that matter).  The crux of the issue is that what fits
most naturally with any-fied generics, <any T> void iterate(List<T> ...),
is today being written using List<?>.  And one of the (predominant?)
reasons that's used today is because of late-binding/reflection where the T
isn't known at compile time.  I don't think anyone is claiming there's any
subtype relationship between List<int> and List<?> from an OO perspective.

On Thu, Jan 22, 2015 at 2:13 PM, Remi Forax <forax at univ-mlv.fr> wrote:

>
> On 01/22/2015 07:33 PM, Brian Goetz wrote:
>
>> Short answer: yes.  (Some of the reasoning for this is reconstructed in
>> the latest State of the Specialization.)
>>
>> The key requirement was, and continues to be: gradual migration
>> compatibility.  This has multiple facets:
>>  - It should be practical to generify an existing class (within reason),
>> rather than throwing it out and starting over
>>  - It should be practical to generify libraries gradually, for example
>> generifying a superclass separately from a subclass
>>  - Generification of libraries and their clients must not require a "flag
>> day".  It should be possible to generify the library first and generify the
>> client later (or not).
>>
>> We have the same requirement now; existing generic classes should be
>> extendable to any-fied generics, it should not be necessary to any-fy
>> libraries all at once (though they do have to be any-fied top-down), and --
>> most importantly -- existing client code must continue to work against
>> any-fied libraries.
>>
>> What is meant by "continue to work" can be subtle, though.  For example,
>> some have balked at the idea that List<?> would continue to mean List<?
>> extends Object> -- as it always has meant -- is not "continuing to work",
>> because it's not "what the user thought they meant when they wrote it ten
>> years ago."
>>
>
> I disagree on that point, in Java, subtyping is defined on object types
> not on primitive types,
> this is why by example the following code doesn't compile even if it's
> technically possible to change
> the way bridges are generated in order to compile it.
>
> class A {
>   double foo() { ... }
> }
> class B extends A {
>   int foo() { ... }
> }
>
> The Liskov principle is defined on objects not on primitive, we have the
> same limitation in Java.
>
> While I agree that Java is the last language with a strong separation
> between primitive types and object types. It's how Java was defined, so I
> don't think it will surprise anyone if there is not subtyping relationship
> between List<?> and List<int>.
>
>
>> But, yes, the requirement in 5 were centered around gradual migration
>> compatibility from non-generic to generic; we have the same requirements
>> when migrating from generic to "any-generic".
>>
>
> strong backward compatibility is in the Java ADN, it's a pain, it's a
> curse, but it's also a blessing because it makes its evolution possible.
>
> Rémi
>
>
>
>>
>> On 1/22/2015 12:46 PM, Vitaly Davidovich wrote:
>>
>>> By the way, is it fair to say that one of the main reasons generics were
>>> implemented with erasure back in Java 5 was also for backcompat reasons?
>>> If so, here we are many years down the road, with lots more code,
>>> patterns, familiarity, etc to preserve, where that decision is making it
>>> harder to evolve the language (and where reification, or at least some
>>> form of it, is going to be done anyway, but at higher cost now
>>> potentially).  Just saying :)
>>>
>>> On Thu, Jan 22, 2015 at 12:19 PM, Vitaly Davidovich <vitalyd at gmail.com
>>> <mailto:vitalyd at gmail.com>> wrote:
>>>
>>>     I hear you Brian, and by no means think I have THE answer.
>>>
>>>         On the other hand, we've seen some impassioned defense of "I
>>>         want to keep being able to use List<?> (or raw List)" on this
>>>         list -- and .NET doesn't even have an analogue of these types,
>>>         you have to use generic methods to abstract over types. So
>>>         while one might find the .NET type system "better", we must
>>>         acknowledge it doesn't provide Java developers with the tools
>>>         they're used to.  (You could argue this is a feature rather than
>>>         a bug; in a world with no existing code or developer experience,
>>>         this might be true, but that's not the world we're in right now.)
>>>
>>>
>>>     I'm not sure "tools they're used to" is all that meaningful, IMHO.
>>>     Erased generics were added, no precedent in java prior to that.
>>>     Lambdas were added, no precedent to that beforehand.  JMM was
>>>     revised, no precedent.  Fork join added.  Streams added. Value
>>>     types will be added.  By definition, things will not always be "what
>>>     people are used to" unless the language doesn't adapt and progress.
>>>     Again, just my opinion of course.
>>>
>>>         And this is the essential tension; a solution that retains
>>>         compatibility (not necessarily just with existing code, but
>>>         people's existing expectations of how it works) is necessarily
>>>         going to result in a "worse" language going forward. There's no
>>>         magic solution here (though there are bad solutions), the art is
>>>         putting the pain where it is felt least.
>>>
>>>
>>>     What does compatibility mean in this particular context? I argue
>>>     that "code compiles" is a low barrier here -- value types are a
>>>     completely new concept to java, and calling "old" code that simply
>>>     took Collection<?> is not necessarily backcompat, for the reasons I
>>>     mentioned.  Also, as I mentioned above, there's nothing wrong with
>>>     re-learning things to adjust expectations when new things are added.
>>>
>>>     See, I don't want a "worse" language just to drag along historical
>>>     artifacts :) The language is going to outlive (if it remains
>>>     relevant and "refreshed") the vast majority of existing
>>>     libs/frameworks/etc that are being alluded to in this thread.  I'm
>>>     not saying java should be evolved recklessly nor carelessly nor
>>>     ignorant of existing code, but I'd say the bar for "we're going to
>>>     make the language/type system/compiler/JVM/etc a bit 'worse' for the
>>>     sake of framework/lib/code Y" has to be very high.
>>>
>>>
>>>     On Thu, Jan 22, 2015 at 11:32 AM, Brian Goetz
>>>     <brian.goetz at oracle.com <mailto:brian.goetz at oracle.com>> wrote:
>>>
>>>         Thanks Vitaly, explicating how things are done on .NET is highly
>>>         constructive, even if we can't just "do what they did."
>>>
>>>         On the other hand, we've seen some impassioned defense of "I
>>>         want to keep being able to use List<?> (or raw List)" on this
>>>         list -- and .NET doesn't even have an analogue of these types,
>>>         you have to use generic methods to abstract over types. So
>>>         while one might find the .NET type system "better", we must
>>>         acknowledge it doesn't provide Java developers with the tools
>>>         they're used to.  (You could argue this is a feature rather than
>>>         a bug; in a world with no existing code or developer experience,
>>>         this might be true, but that's not the world we're in right now.)
>>>
>>>         And this is the essential tension; a solution that retains
>>>         compatibility (not necessarily just with existing code, but
>>>         people's existing expectations of how it works) is necessarily
>>>         going to result in a "worse" language going forward. There's no
>>>         magic solution here (though there are bad solutions), the art is
>>>         putting the pain where it is felt least.
>>>
>>>         Anyone who thinks they have "the" answer to this problem
>>>         obviously doesn't understand the problem.  So for those trying
>>>         to contribute: it would be more helpful if, rather than coming
>>>         at it from an "I have the answer" perspective, try something
>>>         more like "I might have a small piece of an answer." Being in
>>>         such a mental place is far more likely to result in real
>>>         contribution!
>>>
>>>
>>>         On 1/22/2015 10:11 AM, Vitaly Davidovich wrote:
>>>
>>>             Ok, got you.  It's detected at runtime just like
>>>             dereferencing a null or
>>>             indexing outside the bounds of an array -- nothing sound
>>>             about these, but
>>>             java's a safe language so has the safeguards.
>>>
>>>             By the way, the issue of List<T> not being covariant with
>>>             List<super of T>
>>>             was also a drag sometimes in .NET where you knew you weren't
>>>             mutating the
>>>             list and only wanted to read the values (which is safe).
>>>             So, C# has the
>>>             in/out keywords when you define the generic type (only works
>>>             on interfaces
>>>             and delegates) -- compiler then checks your signatures:
>>> https://msdn.microsoft.com/en-__us/library/dd469487.aspx
>>> <https://msdn.microsoft.com/en-us/library/dd469487.aspx> and
>>> https://msdn.microsoft.com/en-__us/library/dd469484.aspx
>>> <https://msdn.microsoft.com/en-us/library/dd469484.aspx>.
>>>
>>>             I hate to keep tooting .NET's horn on this list, but I am
>>>             impressed with
>>>             how they've addressed these various issues.
>>>
>>>             On Thu, Jan 22, 2015 at 9:46 AM, Stéphane Épardaud
>>>             <stef at epardaud.fr <mailto:stef at epardaud.fr>> wrote:
>>>
>>>                 On 01/22/2015 03:42 PM, Vitaly Davidovich wrote:
>>>
>>>
>>>                     Ok can we first agree that List <T> is NOT List
>>>                     <Object>? :) That's
>>>                     unsound since you can't add any Object in there if
>>>                     things are reified.  I
>>>                     think you guys mean List <?>.
>>>
>>>
>>>                        Well, that what I meant by "variance issues
>>>                     aside". It is unsound but
>>>
>>>                 detected at runtime. This is already a limitation of
>>>                 List in Java at
>>>                 compile-time, I'm not proposing to fix it.
>>>
>>>
>>>
>>>
>


More information about the valhalla-dev mailing list