1. 3
  1.  

  2. 2

    The thing I would really like to understand – and somehow no one is able to explain – is how equality and identity works with specialized generics and value types.

    E. g. if you have code like this:

    class Cell<T> {
        T value;
        Cell(T val) {
            value = val;
        }
        boolean contains(T that) {
            return (this.value == that) || (this.value.equals(that));
        }
    }
    

    … and now make it specialized:

    class Cell<any T> {
        T value;
        Cell(T val) {
            value = val;
        }
        boolean contains(T that) { ??? }
    }
    

    How would the implementation of contains look like?

    What would be the semantics?

    Would Cell<Double> and Cell<double> behave identical?

    1. 1

      My guess would be that every value type can be boxed, much like the existing primitives.

      1. 1

        But in which situations would it be boxed?

        Will == be boxed? If yes, how would you recover IEEE equality for floating points, and if it wasn’t boxed, then all generic code would subtly change behavior when people start specializing their generics.

        1. 2

          Maybe I’m misunderstanding your point, but since generics assume everything extends Object, you’d use .equals() instead of ==, and the boxed value type would generate the appropriate logic inside of .equals().

          1. 1

            But how would that “appropriate logic” look like?

            I think the problem is that == does two completely different things on reference types and value types, and while you can implement equals for value types (even without boxing), you can’t really recover == in a generic context that allows both reference and value types.