valhalla-dev Digest, Vol 7, Issue 24

Vitaly Davidovich vitalyd at
Wed Jan 7 23:33:35 UTC 2015

> For value-types:
>     x eq y  -->   (x == y)

You mean for primitives? Custom value types won't work with == as there's
no operator overloading.

Getting back to the null aspect though, here's my take ...

I think we should not introduce a new operator such as eq when we already
have a "universal" equals.  What you really want to say is something like

<any T> void foo(T t) {
    if (T.default.equals(t))
        System.out.println("got default/null");
        System.out.println("got non-default/null");

Now, the obvious problem here is that this NPEs on reference types since
T.default yields a null and you can't reverse the comparison because t may
be null.  So, what you'd like here is similar to what .NET does.  Introduce
an IEqualityComparer<T>-like JDK interface, and provide a way to obtain a
"default" comparer for a given type.  In .NET, there's a generic class
called EqualityComparer, which has a static property called Default (e.g.
EqualityComparer<T>.Default).  That internally (in static constructor)
figures out, based on inspecting T's capabilities and type, which is the
default equality comparer and then hands out that sole instance on each
Default access.  Ultimately, what you want here is instead of doing
T.default.equals(t), you want some other class to define an "<any T>
boolean equals(T x, T y)" which can internally handle one side being null
(for ref types).

tldr; well behaved classes already should be handling null inputs in their
equals() impl, so we should find a way to reuse that instead of introducing
a new operator/keyword.

On Wed, Jan 7, 2015 at 6:07 PM, Thomas W < at> wrote:

> Hi Simon, Vitaly, people,
> Lots of people have been talking about adapting Collections for 'any'
> type. Going forwards, I do not believe we should be writing code that
> explicitly uses/ or checks for nulls (though we may be backwards-compatible
> for a while) any more than we should be writing or calling a Duck.woof()
> method.
> To answering a few questions:
> > a) What are the actual semantics?
> For ref-types:
>     x eq y  -->   (x != null && x.equals(y))
> For value-types:
>     x eq y  -->   (x == y)
> > b) How is this different to the approaches already outlines earlier?
> It provides a basic logical building-block (equality check) at the
> language level, in a way that works both for primitives/valuetypes and for
> nullable references. It addresses a very big long-standing pain point in
> Java application development. It avoids writing/ or encouraging
> "Duck.woof()" style-hacks -- null checks -- into a domain that does not
> uniformly support them.
> > Why do we need a new special operator? What's wrong with using equals
> () and having the specializer rewrite that for primitives?
> > What's wrong with using equals() and having the specializer rewrite
> that for primitives? For other types
> > (refs and custom value types), it should just delegate to the real
> equals.
> To have a proper logical equals in one operator, which is independent of
> implementation & null-safe for reftypes.
> What's wrong is writing null-checks & nulls, in a domain where nulls may
> not exist.
> We are not dealing with Dog, we are dealing with Animal and there should
> be no 'woof()' method.
> > What's wrong with using equals() and having the specializer rewrite
> that for primitives? For other types
> > (refs and custom value types), it should just delegate to the real
> equals.
> What's wrong with an operator that logically has exactly the right
> meaning, without exposing details that don't exist in the domain?
> It also provides a vast benefit for application programmers, as this kind
> of requirement is ridiculously common in hundreds of millions of lines of
> application code.
> Regards,
> Thomas Whitmore

More information about the valhalla-dev mailing list