more background to List<int> specializing List<Any>
Stephen Colebourne
scolebourne at joda.org
Mon Jan 5 01:10:26 UTC 2015
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