
The Java type system is broken - tdurden
http://wouter.coekaerts.be/2018/java-type-system-broken
======
MrBuddyCasino
> Everything is broken. Everything is fine.

This is the correct conclusion. The people getting outraged over this are the
same that will hold long and boring monologues about how everybody does REST
wrong.

~~~
bunnymancer
Had a client just last month that were doing SOAP wrong somehow...

Required a SOAP message, that contained no XML after the message tag, but
instead the entire message body was to be a JSON, and responded with a JSON if
something was wrong, and a fully formed SOAP message if things were Ok.

That and the guys that handle your money use the Http status code as their
personal error messages. Except when the error is on their end, in which case
they return 200 and a JSON with an error message.

There are plenty of ways to do REST wrong, so let's not lump that into the
people that make blog posts complaining about X because X is broken, and
working just fine...

~~~
cs02rm0
_Had a client just last month that were doing SOAP wrong somehow..._

To be fair, I'm not sure there's any other way.

~~~
mey
There are degrees, sort of like levels of hell. I think the universe implodes
if you combine XML Encryption and SOAP SMTP binding. Actually that may explain
things pretty well...

------
mcculley
The mess that is the current Java type system makes me skeptical when
proponents of languages like Go say not to worry, that generics can be added
later.

If Java had generics in the beginning, it would look a lot different and the
type system would be more powerful and safe.

~~~
tabtab
Just use dynamic or better yet type-tag-free languages. Types are hard to get
right and hard to reason about. Sure, there are some Sheldons out there who
master it even under pasta applications, but most of us are not Sheldons. C#
also bleeped up types by adding nullable types, making reflection into a
scavenger hunt.

For dynamic or tag-free languages, type indicators could be used to parse-
check scalar (base) values to see if they are interpretable as the intended
type:

    
    
       function foo(int a, date b) {...}
    

This would be equivalent to:

    
    
       function foo(a, b) {
         if (! parsableAsInt(a)) throwTypeError(...);
         if (! parsableAsDate(b)) throwTypeError(...);
       }
    

And don't overload operators, such as how some languages use "+" to mean both
arithmetic addition and string concatenation. Use a different symbol for
concatenation like PHP does.

~~~
twblalock
I prefer my type errors at compile time.

You have to reason about types in any language because passing the wrong type
to a function can result in errors. You have to do all of that mental work by
yourself in a dynamic language because there isn't a system to do it for you.

~~~
tabtab
There are tools roughly similar to C's "lint" that can warn you about
suspicious-looking code. While compile-time checking can be nice, compiler-
oriented languages often result in more verbose code. Verbosity introduces
errors also. But the benefit weighing also depends on the kind of
applications. I didn't mean to trigger a "holy war" of static versus dynamic
languages.

~~~
runeks
> Verbosity introduces errors also.

The purpose of types is to introduce errors in the first place - at compile
time, if you messed up.

Wrong code causes errors regardless. Annotating with types just moves this
event from runtime to compile time.

~~~
tabtab
I understand that, but I'm not sure the benefits exceed the drawbacks. In
other words, verbosity introduces errors by making the code harder/longer to
read. The type-related verbosity may reduce errors, but perhaps not enough to
counter those caused by verbosity. In my experience, it's roughly a wash, but
depends on a lot of other things, like frameworks used, skill of developers,
QA techniques, etc.

------
bad_user
It’s pretty tragic how people respond to such criticism emotionally, instead
of acknowledging the issues and working towards fixing them or educating
others in the traps and compromises involved.

HN is less prone to toxicity, but this is reminiscent of Reddit and it drives
away the people that want to help.

As a piece of advice, some type theory never harmed anyone ;-)

~~~
nine_k
Application of type theory, or any theory, or any formal method, requires
humility and patience.

To apply a formal method to your work requires to acknowledge that your
intuition might me wrong, your past decisions incorrect, and your knowledge of
the subject area deficient. Often you have to step back, rethink, and rework.

This is a normal mindset for a scientist, and a pretty common mindset for an
experienced engineer.

But this view is not automatically acquired with an engineering diploma, with
obvious coding skills, or even with a couple successful open-source projects.
It has to be nurtured consciously—or rammed down your throat by unforgiving
reality; the latter is pretty traumatic.

~~~
pjmlp
It is also tribalism.

When one is a polyglot developer, we are like mercenaries, a bag full of
tools, each with its caveats, and we care about the solution less how we got
there juggling those tools.

Developer X tend to keep searching for external confirmation that they did the
right choice. Any attack on tool X triggers defensive attacks, as if they
would be a personal attack.

Of course I am exaggerating here, just extrapolating from those that I know on
my circle.

~~~
frockington
It is also really easy to look over flaws when you work around them everyday.
I used to be on the java hate train but now after using it daily I can barely
remember why I used t take issue with it

------
TazeTSchnitzel
My favourite feature of Java's type system is that, because any object type
also accepts null, the type system is unsound and you can convert anything to
anything else:

[https://raw.githubusercontent.com/namin/unsound/master/doc/u...](https://raw.githubusercontent.com/namin/unsound/master/doc/unsound-
oopsla16.pdf)

~~~
stingraycharles
Wouldn't that be a problem in most languages? Even Haskell allows for it
through Data.Dynamic

If I can serialize to String, and then deserialize a String to any type of
class, I can effectively "cast" anything to anything.

~~~
tathougies
Data.Dynamic is type safe. It performs a run-time type check.

Haskell can be made to be unsound using 'unsafeCoerce', but as you'll note,
there is a giant unsafe in front of it.

~~~
chowells
Haskell is unsound because of 'undefined :: a'. There you go - a proof of
every proposition by the Curry-Howard isomorphism.

It's still safe, though, as it diverges at run time. Much like the
ClassCastException coming from the JVM prevents the unsoundness in the
original article from being a safety error.

'unsafeCoerce' (and things that can implement it, like creating a polymorphic
mutable cell with 'unsafePerformIO') are worse than unsound - they are also
unsafe.

------
viach
From the examples: "String s = gridWrapper.get(0).get(0).get(0);" \- Java type
system is broken!

Java is not perfect, but this looks to me like a broken code indeed
".get(0).get(0).get(0)".

Could we rephrase the message of the article as "If you write really broken
code in Java, you might be not guarded by the type system". And this is, well,
uhm, well... acceptable?

~~~
rimunroe
Is a type system really worth that much if it can't help you in a situation
where your code is ugly and hard to follow?

~~~
stickfigure
Unequivocally, yes.

Several new languages (eg Typescript, Dart) have _optional_ type systems that
still bring significant value to the table.

Sure - all other things being equal, I'd much rather have a type system that
is completely sound. Ceylon's type system is _beautiful_ and I'm happy to see
its union + intersection types being adopted by Typescript. But honestly, I'm
not going to lose much sleep over these particular issues in Java. Bad code
gets refactored.

A bigger complaint should be made that generic type erasure makes libraries
hard (eg, the number of places you have to pass around Class<?> or
TypeReference objects to let the runtime know what to do). But that was a
clearly a compromise decision and everyone knows about it.

~~~
igouy
> … Dart… have optional type systems…

 _fyi_ "Dart’s type system is now sound" and "…types are mandatory".

[https://www.dartlang.org/guides/language/sound-
dart](https://www.dartlang.org/guides/language/sound-dart)

~~~
stickfigure
Wow great news! That makes Flutter even more exciting.

------
buremba
Welcome to the world of enterprise-ready complex applications. I agree that
these cases should be covered by the compiler but man, there are mainstream
languages that don't implement generics just because they're complex and
pretend that they're not helpful.

It would be nice of you to compare Java generics with equivalents instead of
just criticizing it. It doesn't help anyone writing "this is broken" not
offering any alternatives or suggesting ways to fix the problem.

~~~
pdpi
Clearly you didn't reach the conclusion. First, because the conclusion is not
"Java sucks", but rather "Most of these things, while not kosher, are unlikely
to happen in practice." Second, because the author didn't just leave it at
criticising the language — he opened a bunch of bugs in the OpenJDK tracker.

~~~
bad_user
People criticizing constructive criticism are often not constructive.

------
hyperpape
Here's another fun trick, though it's probably not a flaw in the type system:
[https://twitter.com/joshbloch/status/1018987317489426432](https://twitter.com/joshbloch/status/1018987317489426432).

~~~
dlubarov
Another flaw we can abuse is Java's covariant array types:

    
    
        Object[] objects = new Integer[] {1, 2, 3};
        objects[0] = "hello";
    

Also compiles but fails at runtime.

------
kazinator
Disagree with bullshit term: _heap pollution_.

Pollution is the proliferation of superfluous objects creating some sort of
undesirable mixture. For instance "namespace pollution".

An inconsistency between the run-time type of an object in the heap, and the
type of the expression in the program which refers to that object, isn't a
good fit for the word "pollution".

Quit trying to pollute the computing lexicon with nonsense.

~~~
kazinator
Looks like this is a thing in Java culture; good grief.

------
olliej
It missed my favorite: contravariant arrays (or is it covariant, I last did
work on this more than a decade ago.

Specifically you can do (forgive syntax it’s also been a long time since I
wrote java)

X = new String[10] Ovject[] o = X

o[0] = 1; // this will auto box, and then fail at runtime

Note that this isn’t a “bug” as it predates any version of generics so
collection types especially are much saber if you support this. That said it
does result in a logical error in which you can’t assign something that looks
like it should be fine.

.Net unfortunately picked up this design decision in order to support java on
their vm.

------
exabrial
Website is struggling, here's a cache:
[http://archive.is/k2YbA](http://archive.is/k2YbA)

------
raj7749
I was trying to justify the type safety of list in java to one of my senior, i
am glad that i was right, it is indeed broken

------
npstr
Java generics are broken? What else is new?

------
Froyoh
Not broken. Working as intended.

~~~
lmm
Nonsense. There are four bug reports at the bottom of the article; all seem to
have been accepted as bugs and one has already been fixed.

------
wintorez
* The Java is broken

------
nik736
Java is broken ¯\\_(ツ)_/¯

------
whatyoucantsay
This fact may be hacker but it is _not_ news.

------
bunnymancer
Oh good, another opinion about how this one thing in this one language is the
worst thing ever, and also works just fine.

Find something that bothers you, complain publicly, do absolutely nothing
after that, repeat.

