Problem of defender methods with generic methods
Ali Ebrahimi
ali.ebrahimi1781 at gmail.com
Mon Nov 15 02:51:11 PST 2010
Hi Maurizio,
Comments inlined.
On Mon, Nov 15, 2010 at 1:32 PM, Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:
> On 15/11/10 08:55, Steven Simpson wrote:
> > Hi,
> >
> > On 06/11/10 04:55, Ali Ebrahimi wrote:
> >
> >> public interface CustomizedList<T> extends List<T> {
> >> <A extends Comparable<? super A>> extension A max() default
> >> Trait.<A>max;<============= cannot find symbol A
> >>
> > What is this supposed to mean, especially to a caller? AIUI,
> > CustomizedList.max will appear to the caller as a regular virtual
> > method, and the caller has no knowlegde that it is somehow bound to
> > Trait.max.
> >
> I think that the above signature wrong - the problems you see (i.e. the
> fact that you can call max on a List<Runnable>) stems from the fact that
> type-variable A and type-variable T are unrelated.
>
> The reason for this issue is current Compiler restriction.
if compiler can accept the following syntax:
<A extends T & Comparable<? super A>> extension A max() default
Trait.<A>max;
The aim is here to restrict calling of max only on CustomizedLists of
Comparables, otherwise compiler raise compile time error.
I know this is a new concept- a kind of conditional inheritance. but
currently this can not be implemented in java, unless by introducing a new
subinterface. then we have two interfaces.
public interface ComparableList<T extends Comparable<T>>
extends CustomizedList<T> {
extension T max() default Trait.<T>max()
}
public interface CustomizedList<T> extends List<T> {
extension CustomizedList<T> filter(Predicate<T> predicate) default
Trait.<T>filter;
<R> extension CustomizedList<R> map(Extrator<T,R> predicate)
default Trait.<T,R>map;
...
}
From the caller's perspective, calling max() on a List<T> should return
> T - which means that the signature of max() should be something like:
>
> public interface CustomizedList<T> extends List<T> {
> extension T max() default ...
> }
>
>
> Now let's take a look at the class Trait - since what we had is similar
> enough to Collections.max I think we should keep it:
>
> public static class Trait {
> public static<R extends Comparable<? super R>> R
> max(CustomizedList<? extends R> self) { ... }
> }
>
>
> The only bit missing is: how are the extension method and the static
> Trait method linked together? The problem is they can't - at least not
> now: if you try to do this:
>
> public interface CustomizedList<T> extends List<T> {
> extension T max() default Trait.<T>max()
> }
>
> You will get a compilation error, as T is not statically suitable for an
> R whose bound is Comparable<? super R>.
>
> On the other hand, we are talking about adding methods to perform
> _comparisons_ on the contents of a collection - which seem to imply that
> the collection itself must contain elements which are some subtype of
> Comparable. Therefore, I think the right signature would be:
>
> public interface CustomizedList<T extends Comparable<T>> extends List<T>
> {
> extension T max() default Trait.<T>max()
> }
>
>
>
> Which would compile w/o problems (and the right semantics will be
> enforced by the compiler - no new syntax required).
>
> Maurizio
>
> Best Regards,
Ali Ebrahimi
More information about the lambda-dev
mailing list