P.S.

1. While language-level extension methods (no JVM involvement) won’t solve the 
deprecated-method problem, they do solve the Stream<int>.sum problem, and quite 
elegantly. That is an orthogonal feature which could be added in a later 
version, and in a compatible way (static methods could be turned into extension 
methods) with a simple new static-import statement. Instead of one 
not-too-general and a little strange solution, we can have two general and 
completely orthogonal solutions, which are also probably simpler to implement, 
and, IMO easier to understand. Yes, there’s a big price to pay, but it is 
stacked against a big chunk of complexity which may be avoided.


2. The method-hiding solution that I suggest might also serve as a nice part of 
the solution to the 64-bit (or John’s generalized) indexing problem. The 
int-indexed methods will simply be hidden from Java 10 code.


Ron



> On Dec 22, 2015, at 11:36 AM, Ron Pressler <[email protected]> wrote:
> 
> 
>> 
>> On Dec 22, 2015, at 1:55 AM, Brian Goetz <[email protected]> wrote:
>> 
>> 
>> 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.
>> 
>> 
> 
>> 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.
>> 
>> 
>> 
> 
> I agree with everything, but it all comes down to the following question: 
> does backwards _source_ compatibility alone, something that Java has good 
> coping mechanisms for (javac source level, IDE/tool support) justify the 
> addition of a feature that is not trivial and not very general (certainly not 
> as general as extension methods)? We’re talking about receiver type-matching 
> that is finer-grained than a class, something that feels foreign (and 
> “un-simple") in OOP.
> 
> 
> 
>> 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.
>> 
>> 
>> 
> 
> But couldn’t it be just as good a replacement even if some of the methods 
> were plain static methods, something Java developers are quite familiar with? 
> It will require code migration either way. Yes, it won’t have the same 
> fluent-API, but neither will other methods that people will come up with. Is 
> hand-specializing the _public interface_ (I have no qualms with 
> hand-specializing hidden implementation) a necessary enough feature to 
> justify non-class-based receiver-type-matching? It feels like a new and 
> unfamiliar form of ad-hoc almost-but-not-quite extension methods (sadly, 
> actual extension methods won’t solve the problem). If anything, backwards 
> source compatibility is a stronger argument, as it is very important (though, 
> IMO, not important enough to justify this).
> 
> 
> Default methods had both the urgency — binary compatibility — and the 
> generality. It seems to me that partial methods have neither. I’m not saying 
> they’re not a cool feature or that they don’t solve the problem, but they 
> don’t feel very blue-collar.
> 
> 
> Anyway, I’ve said my piece on this matter :)
> 
> 

Reply via email to