caution: bleeding-edge ahead!

Victor Nazarov asviraspossible at gmail.com
Mon Jan 19 11:10:52 UTC 2015


I still think that class aliasing is the clearest approach proposed. And
I'd like to express my support for this direction.

If we can really make

IntStream.class    to be the same as    Stream<int>.class

and

new IntStream()    to be the same as    new Stream<int>()

We can easily and cleanly implement peeling on top of it.

List example will look like this.

List.java
    interface List<any T>
        extends Collection<T>
        specializations __WhereRef(T) ObjectList,
                              __WhereInt(T) IntList {

        /* ... */
        T removeByIndex(int index);
        T removeByValue(T value);
    }

ObjectList.java
    interface ObjectList<T> extends List<T> {
        T remove(T value);
        T remove(int index);

         default T removeByIndex(int index) {
             return remove(index);
         }
         default T removeByValue(T value) {
             return remove(index);
         }
    }

IntList.java
    interface IntList extends List<int> {
        int max();
        int min();
    }


When interface is used in class declarations, specialized interface version
is used:

class OldList<T> implements List<T> {
}

Since T is defined as reference above declaration actually the same as :

class OldList<T> implements ObjectList<T> {
}


This seems clean enough but it spawns some complexity that manifests itself
as follows.
I don't know if it this complexity worth it.

class ArrayList<any T> implements List<T> {
}

It seems that

ArrayList<int> should implement IntList

and

ArrayList<Object> should implement ObjectList

ArrayList should somehow inherit set of specializations and implement
different set of interfaces with different type variables.

ArrayList<int> a = new ArrayList<> ();
a instanceof IntList; // ===> true

ArrayList<Object> b = new ArrayList<> ();
b instanceof ObjectList; // ===> true

ArrayList definition should be checked to correctly implement all
specialized interfaces. Since missing interface method implementation
should better be a compile-time error, that run-time (specialization-time
probably) one.

This compile time check is only feasible if we put some constraints on
specialization interfaces, like:

    "interface used as a specialization should provide default
implementation for all of it's methods"

Usage of List interface should use specialized version too:

class Test<T> {
  List<T> list;

  void method1(T value) {
    // Since T is reference type, list should be instance of ObjectList
interface and have remove method
    list.remove(value);
  }
}



Victor Nazarov

On Sun, Jan 18, 2015 at 6:29 PM, Brian Goetz <brian.goetz at oracle.com> wrote:

> If this will be achieved (and that's a big IF), then may be it can be
>> pushed even further to:
>>
>> IntStream.class == Stream<int>.class
>>
>
> Note that IntStream is not simply the result of "take Stream<T> and
> replace T with int."  It has methods not in Stream (e.g., sum()), and some
> of the specialized methods not only specialize T -> int but things like
> Supplier<T> -> IntSupplier.
>
> So the above equality is even a bigger "if" than you are probably
> imagining.
>


More information about the valhalla-dev mailing list