Equality
Peter Levart
peter.levart at gmail.com
Wed Dec 23 16:30:55 UTC 2015
Hi,
Sometimes I miss a feature in generic type declarations where one could
refer to a type variable of a super type without repeating it in the
declaration of the generic type. For example, currently one has to write:
interface Snapshooter<E, C extends Collection<E>> {
C snapshot();
boolean addElement(E e);
}
Snapshooter<String, List<String>> strings = ...;
List<String> snapshot1 = strings.snapshot();
strings.addElement("abc");
List<String> snapshot2 = strings.snapshot();
What if E could be implicitly declared like:
interface <E> Snapshooter<C extends Collection<E>> {
C snapshot();
boolean addElement(E e);
}
Snapshooter<List<String>> strings = ...;
Which would be similar to declaring:
interface Snapshooter<C extends Collection<?>> { ... }
...with added benefit that one could refer to E from Collection<E>.
I don't know if this could be soundly incorporated into the language
type system, but if it could be, and if interfaces could also be
implemented by value types, then...
On 12/19/2015 05:38 PM, Brian Goetz wrote:
>> Anyfy equals, and adjust default implementation of boolean
>> T.equals(any x)
>
> I think we may be talking past each other (while basically saying the
> same thing from opposite directions.)
>
> "any" is not a type; it is a modifier that affects the domain of type
> variables. So we don't have (and I think we don't want) a meaning for
> equals(any x). But what we do want, is a way of expressing "I'll take
> anything which could be on the other side of the == operator with me."
> For refs, that's Object; for a value type V, that's just V.
>
> Where we had gotten with the <V super U> / superation idiom (not
> suggesting either of these syntaxes is great) is being able to express:
>
> - If T is value, then T, else the erasure of T (usually object) **
>
> I'll write this as Sup<T> for short. The convenient thing about
> Sup<T> is that it conveniently collapses to Object in the places where
> we want Object, so we could define contains/remove as
>
> contains(Sup<T>)
>
> and contains will always bottom out at equals(), so equals() similarly
> needs to be
>
> equals(Sup<Self>)
>
> If this is a valid approach (and I think its the best one we've got so
> far), then we're looking for how to spell Sup<Self> (in all of: type
> system, language syntax, bytecode descriptors.)
....there could be a special interface:
public interface Any<any T extends Any<T>> {
boolean equals(T x);
}
...implemented by Object:
public class Object implements Any<Object> {...}
...and implicitly implemented by every value type:
public value ValueType [ implements Any<ValueType> ] {...}
Sup<E> from Collection<any E> could then be expressed as:
public interface <T> Collection<any E extends Any<T>> extends Iterable<E> {
boolean contains(T x);
...
Regards, Peter
>
>> I still think that doing something like this removes the need
>> to specially deal with Collection.contains and related methods.
>
> I don't see it yet; those signatures are still currently
> contains(Object), which isn't appropriate for value types. So we have
> to do *something*.
>
>
>
>
> ** There's a lot of sloppiness in the ref/val distinction, which is
> going to need to be cleaned up. Sometimes when we say ref/val, we
> mean "erased/reified". Sometimes we mean "polymorphic/monomorphic".
> Sometimes we mean "nullable/non-nullable."
More information about the valhalla-spec-experts
mailing list