more background to List<int> specializing List<Any>

Remi Forax forax at univ-mlv.fr
Mon Jan 5 11:41:55 UTC 2015


About List<int> not being a subtype of List<?>,
You can note that in Trove, the specialized classes doesn't inherits from
the interface of Collection API. You have to use decorators for that.

Using the same idea (delegation is sometimes more powerful than direct 
implementation),
the interface List<int> can have a method boxed() that returns a view of 
the list
as a List<Integer>. At least the performance model (who do boxing, who 
don't)
will be clear.

Rémi

On 01/05/2015 02:10 AM, Stephen Colebourne wrote:
> On 4 January 2015 at 23:20, Brian Goetz <brian.goetz at oracle.com> wrote:
>> Zooming back, though, I think what you're really saying is: the part where
>> List<int> is not a subtype of List is really the part you dislike the most,
>> because it lives in this weird middle ground between "all instantiations of
>> List<T> have a common supertype" (Java 5 generics) and "no instantiations of
>> list<T> have a common supertype" (C++).  You are probably OK with either all
>> (what you've got now) or nothing (if you hadn't had ten years of Java
>> generics training you on homogeneous translation), but what really freaks
>> you out is this half-here, half-there, that forces the user to be aware that
>> reference instantiations are erased and value instantiations are reified,
>> with all that entails.
>>
>> Is that really your concern here?
> My concerns are, *at this point*, somewhat larger than that. Right
> now, my concern is that the combination of changes may well be making
> Java as a whole worse, not better. Right now, I'm in the camp that I'd
> rather reject adding value types because the negatives appear to
> outweigh the positives. I do, of course expect this judgement to
> change as things develop, but it is a big concern I've been mulling on
> over the holiday period.
>
> The parts I like include
> - JVM optimisations for types that don't require a synchronization lock
> - greater locality of data, within the parent object
> - the potential for arrays of value types
> - maybe ClassDynamic might be useful, but its very hard to tell at this point
> - distinguishing types that don't have identity and optimising based on that
>
> The parts I don't like include
> - making old code incompatible with new code (see below)
> - that List<int> is not a subtype of List<?>, List<T> or List<Integer>
> - that Object changes its meaning (see below)
> - that List<?> changes its meaning (see below)
> - that instanceof changes its meaning
> - that Class changes its meaning
> - that there is more "weirdness" not less
> - that the thrust is to create more primitive types, not unify those we've got
> - that there is too much concern on memory/performance and not enough
> on developer productivity - Java isn't C
>
> Thinking about the negatives, a lot relate to primitive types always
> causing problems in code today (typically framework code). With 8
> special cases today, its managable. With an entire world of special
> cases, its not. Of course the plan is to make them not special cases,
> but what I'm seeing so far is making the bifurcation bigger not
> smaller (worse not better).
>
> I have a particular problem with the proposal where IMO it makes old
> code incompatible with new code. Consider an OSS library released for
> JDK8 that has a method process(Object). The intent is that the method
> accepts anything, we don't care what the type is. When used with
> JDK10/11 it still accepts anything, except that instead of a small,
> known number of types being boxed (for which the library might have a
> process(int) overload, there are now *lots* of boxing operations.
> Technically, thats compatible, but in practical terms the boxing makes
> it incompatible (performance/gc).
>
> Of course the situation with process(List<?>) is worse again. Here I
> want to accept any list, I don't care what type. In JDK 10/11 it now
> won't even work. Callers won't be able to pass in a List<valuetype>.
> (As opposed to IntList which can be passed in providing it extends
> List<Integer>, and which could be handled specially internally within
> process(List<?>) using instanceof if necessary). Note that while the
> method process(List<?>) could be fixed to work by using <any T>, OSS
> libraries don't work like that - they can't just have a new release as
> they have to still support developers who can't upgrade. ie. I fear
> that value types will badly bifurcate the ecosystem.
>
> TLDR, Object is *already* the Any type, and List<?> is *already* the
> List<Any>. Breaking that is a big problem for me.
>
> Given how it looks that value types would actually work in the JVM,
> thats why I'd rather have no value types than the ones currently on
> offer.
>
> On your original question about List<T> specifically, I've coded one
> piece of source code so I have one class. 1:1. The type is unimportant
> most of the time - its a compiler fiction. A List is a List is a List.
> Thus its not the half-there half-not aspect that bothers, but losing
> 1:1.
>
>
> Some other thoughts and vague ideas as I've been mulling on this.
>
> Separating synchronization from Object seems like a Good Thing.
> Possible approach: add interface Lockable with locking methods from
> Object. Remove methods from Object using JDK 9 as a stepping stone via
> deprecation. Use classloading/module linking tricks to add Lockable
> interface to all classes that were compiled in JDK 8 or earlier.
>
> Fixing up the List.remove(int) vs List.remove(Object) problem seems
> like a Good Thing. But its a more general problem: Why not just rename
> the method? Use JDK 9 module linker step to bind the old method name
> to the new method name. (Being able to rename methods and be backwards
> compatible would be a major gain for all large Java systems). Same
> renaming strategy applies to many of the problem cases under
> discussion.
>
> Special casing the 8 primitive types in generics, with List<int>
> extending List<Integer>. (Hence my original question).
>
> Instead of value types, some form of "packed objects" seems like an
> alternative that might have less issues. By packed objects I mean
> where the state of the child object is embedded in the parent object.
> (Child objects are not seen by gc, have no identity and are copied
> where necessary, Null handled with bit flag where necessary. Variables
> extended to be able to point to a child within a parent or an item in
> an array. And yes, this is super-vague, and could be worse than value
> types).
>
> All of the above focussed on providing similar results to developers
> without the seemingly evil value types.
>
>
> I'm very aware of where you are in this whole process, so there is no
> need to respond to each of my vague thoughts (and I'd encourage others
> not to jump in to avoid wasting too much time here). I do trust that
> things will improve. But I'm not currently optimistic that they will
> improve enough.
>
> Stephen



More information about the valhalla-dev mailing list