> So, you are suggesting then that if a static type system doesn't have sum types, it provides no value and you are better off without it,

There are alternatives to sums, like union and intersection types, with different tradeoffs. Nominal sums are what you could call “proven technology”: they integrate well with other desirable language features like type inference and ML-style modules with abstract types. Unions and intersections, OTOH, can be flexibly sliced or aggregated without defining new nominal types.

But there has to be some way to perform case analysis in a principled way.

> and I'm pointing out that as annoying as that might be, there is still plenty of value without them.

I don't see any value in a type system in which I can't accurately model whatever problem domain they throw at me, and case analysis is basically omnipresent in programming: Without loops you can't write a nontrivial program, and, without case analysis, you can't have non-infinite loops!

Type system - Accurate modeling = Annoying bureaucracy.

> Java actually has SumType's for the simple cases of representing two types (Pair<K,V>) or for representing one type or null (Optional<T>).

> For the rest of the cases, you'd either have to recursively use Optional<> and/or Pair<> or come up with your own type name, but considering you have to name everything else anyway, and you have to handle the various cases involved, it's not that bad to create a static inner class for some new combination of values. It's not elegant, but it really doesn't add much work.

Just because I can make a type isomorphic to the one I want (assuming I don't peek into the internal representation, which reflection always lets me do), it doesn't mean the one I get is equally convenient to work with. Can you imagine pattern matching on abstract syntax trees or other complicated mutually recursive data structures in this way? Even the visitor pattern sounds less painful, and that says a lot.

> If you feel it does, use an attribute processor to make it easier to generate one on your behalf.

Then I can't understand my code in terms of itself. I'd have to know what the attribute processor works transforms it into.

> Yes, we're all very proud of the correctness of having a distinct type for null/nil/none/whatever. It's nice, but from a practical standpoint you can achieve the same thing in Java.

From a practical standpoint, in a language with actual sums, I can match arbitrarily nested patterns in a single `case` or `match` block. I can't achieve that in Java. Trust me, it can cut the size of case-analyzing code by a factor of more than 3.

> You just can't fix the existing class library.

If the class library were the only problem, then the solution would be to make a new one. But even a new library couldn't give me the niceties I described above.

> Well, in physics, "no magnetic field" != "no gravitational field", so...

A zero potential field isn't a null reference to anything. It's just a normal potential field whose value at every point is zero. Do you have an example where:

(0) the identities of two objects with the same physical properties matters, that is, where swapping two objects with the same physical properties can make the system behave differently, and

(1) the laws of physics are formulated in terms of nullable references to such objects?