Lately, as I've been learning more about C++ and Rust, I've realized how well-designed Java is as a language. The folks at Sun must have been quite good to get so many things right.
I feel the need to substantiate this potentially somewhat controversial opinion. To begin with, I'm simply talking about the language itself, the syntax, and thus not considering runtime environments, portability, performance, or anything like that. Of course, the intended target of the programs influences language design, but I want to begin by comparing the languages based solely on syntax.
For me to approve a language, generally three things are required, namely that the language is:
Most languages with substantial userbases already fulfill point 1. Therefore, the last two points may be more relevant
to discuss. Statically typed languages are simply very satisfying. I've played around a bit with the Haskell-based
Agda, and there are indeed few things as rewarding as
when your Agda code finally compiles. For an imperative or object-oriented programming language to be both useful and
statically typed, often a broad typing system is required. Here Java shines in comparison to C++ with its typed
generic classes (templates are not typed in C++, although concepts remedy the situation somewhat). Java allows generic
methods in interfaces and specialization of the return type for abstract methods in inheriting classes, while C++ only
allows such specialization for raw pointers or references. I understand, of course, from an implementation
perspective, the reason why C++ is designed in the latter way, but it is still unfortunate from a syntax point of
view. Related issues with Rust are that, at the time of writing, it is not possible to
upcast from &Derived
to &Base
, or
define the type Box<dyn A + B>
.
Furthermore, languages should have simple syntax rules, few features, and a limited amount of syntactic sugar. There
should simply be as few ways as possible to express the same thing. This is the reason I defend
public static void main
; syntactic sugar like JEP 445 only
hides complexity and makes it harder for learners to understand what the language is really doing. Aside from Oracle's
greed, simplicity and completeness are the reasons why my preferred Java version is still Java 8, but I do actually
also support var
, introduced in Java 10. In my opinion, C++ definitely is the worst programming language
of them all due to it being comically complex and bloated and the fact that people are actually using it (I think C is
a considerably more well-designed language than C++). I also just want to quickly mention the benefit of naming
conventions endorsed by language designers.
There are of course still many missteps present in the design of Java. That the language is entirely object-oriented for one, but I can potentially justified this in the name of minimalism. The fact that it is not possible to instantiate objects of generic types due to type erasure is also unfortunate. But overall, I was struck by the realization of how good the Java syntax still is almost 30 years on, and how well it still compares to more modern languages.