Migrating methods in Collections

Brian Goetz brian.goetz at oracle.com
Mon Dec 21 23:55:06 UTC 2015

>> On Dec 21, 2015, at 8:03 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
>> I think people would be pretty ticked off if Map.get() just went away. 
>> I think the response would be: "Those idiots decided to change their 
>> libraries for their own reasons, I have no intention of ever 
>> specializing my Map, and yet I have to change my code anyway."
> But those same people would also consume an API which returns a List<int> and then find those same methods gone anyway. 

Theres a big difference, though.  The difference is, there is no code today that uses List<int>.  So no existing code will break.  Because anyfying a class or a client is an explicit operation (on the class side, you’re explicitly making a tvar “any”, on the client side, you’re using a List<SomeValueType> which by definition didn’t work before.)  Breaking existing code is far worse than “If you want to upgrade your List<Integer> to be List<int>, you’ll have to adjust a few other things too.”  

As a general rule, the pain of migrating should go to those who want to migrate, and should not fall on those who don’t want to migrate.  So existing Map code that uses reference types and wants to keep using reference types, should be able to completely ignore the changes to the API.  

> Although my suggestion would probably require a tool (a javac plugin?) to migrate sources, though. Go has “go fix”, but Java has had such a tool for a long time (I think James Gosling worked on it). I know I’m making my suggestion sound even scarier, but I think it beats adding a type system trick for the purpose of source compatibility (more on that later).

I have hopes that the IDEs will provide some sort of “migrate to new collections” transform.  The goal there is to reduce the pain of “I wanted to migrate to use List<int>”, but even if this were a one-button thing, I am not sure I’d want to impose it on people who have existing codebases that they have no plans of upgrading to values.  

Another mitigating factor is that the new methods are total.  That means, you can migrate your code to be “any-collections-ready” without actually using any of the anyfied classes, and without changing the semantics of anything.  Which gives us a path to eventually deprecating the old methods — though realistically it would probably be a VERY long time before we removed them.  

> Is the goal to somehow make IntStream into Stream<int> or to deprecate IntStream? If the latter, I also see no reason why sum (but not other sensible operations) must be part of Stream<int>. In any event, a more general solution would be extension methods (I am not proposing we add those). 

Something slightly more ambitious.  I’d like to deprecate {Int,Long,Double}Stream, but allow Stream<int> to respond to all methods currently supported by IntStream.  This provides a path to getting rid of the manual specializations (probably faster than the legacy collection methods) because Stream<int> would be just as good as the old IntStream.  

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/attachments/20151221/09002d02/attachment-0001.html>

More information about the valhalla-spec-experts mailing list