Still working out the details on the supersolution. And figuring out
if I have the time. At this point, without a prototype, I'm not sure
if you can (or, in fact, should) be taken seriously.

I don't think you can just evolve incompatible APIs because you have a
module system, Alex.

Let's say we add a 'filter' method to list. How? We can only change
List if we add List to the versioned set. But if we do that, then any
two modules that require different versions can no longer talk to each
other if the talk protocol involves Lists, which are almost as 'near-
primitive' as Strings. That's not going to fly. You still need a way
for an old 'view' on Lists, or for two separate List libraries to be
able to hand each other wrappers or some other solution to cross this
bridge.

Or you use extension methods and you don't have this problem.


NB: If you want a full proposal, it's very simple:

A) allow static methods in interfaces. There's no sane reason I can
think of for why this is disallowed in the first place.

B) Use an annotation or keyword (@Extension), legal only on static
methods inside interfaces where the first parameter of the method has
a type that is equal to the interface itself. So, this would be legal,
in java.util.List:

 @Extension public static <T> void sort(List<T> list, Comparator<T>
comparator) { /* code */ }

C) Whenever the compiler encounters a call which cannot be resolved
(no such method), then the compiler will back up and look through the
chain of interfaces implemented by the type of the object for which
the call cannot be resolved. If it can match the call to an extension
by moving the object into the first parameter position, then it'll
compile that instead. The fact that this will not behave in a virtual
manner (will not runtime-find implementations on subclasses) is
intentional.


Thus, something like this:

list.sort(someComparator); //not legal now

will then be compiled as: List.sort(list, someComparator);

If there are multiple choices to make, then: If there's one interface
that is hierarchically closer to the target type than any of the
others, that one wins. If you can't make this determination (diamond
pattern; type A implements both B and C, where B and C both have a sort
() extension), then do not choose at all and instead generate a
compile-time error. This can be solved by either calling one explicit
version [use B.sort(me) instead of me.sort()] or fix it in A by adding
a wrapper method, like so:

@Extension public static <T> void sort(A<T> list, Comparator<T>
comparator) {
    C.sort(list, comparator); //We'll explicitly choose C
implementation.
}





On Feb 24, 12:01 am, Alex Buckley <[email protected]> wrote:
> On Feb 21, 8:25 am, Reinier Zwitserloot <[email protected]> wrote:
>
> > Given the sheer amount of work you'd have to do re-engineering the
> > java API, breaking backwards compatibility, or adding extension
> > methods, is really the only way.
>
> Happily, the existence of a versioned module system in JDK7 allows
> incompatible API evolution where it is considered necessary.
>
> Alex
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to