> IDE generated "type safe" code too often is simply "a class for everything" and bad abstractions
> Most of the time when I review code my remarks is: it should be a 10 lines function, why did you write 10 classes with 10 getters and setters each?
Java is an extremely poor example of a helpful type system. Consider OCaml, Haskell, Elm, and others which avoid much of the verbosity you describe.
Static typing is really helpful when doing refactoring. The fact that a statically typed program compiles gives you important assurances - especially post-refactor. It's not a silver bullet but it's also certainly not "playing tennis with the compiler" as you describe.
> Java is an extremely poor example of a helpful type system.
With generics added 15 years ago, lambdas with argument type inference 6 years ago, local variable type inference two years ago, and ADTs and pattern-matching [1] gradually rolling out already, Java is practically becoming an ML. I say that as someone who likes both ML and Java. The two are becoming so similar that I think it's a stretch to claim one of their type systems is more helpful than the other.
But I think people overlook type systems' biggest benefits. Empirical observation has not found any significant benefit to correctness in general (although there seems to be some in particular cases like JavaScript vs. TypeScript and I wouldn't be surprised if we find it in Rust vs. C), but the main benefits are code organisation and tooling support (refactoring, code completion).
In my experience, Java's generics were horribly confusing and not quite type-safe, in contrast to the dead-simple polymorphism in Haskell. But feel free to correct me here.
> ADTs and pattern-matching gradually rolling out already
What a language gives you is less important that what it makes easy, and I cannot imagine a more cumbersome syntax for ADTs than the one in the linked proposal.
> In my experience, Java's generics were horribly confusing and not quite type-safe, in contrast to the dead-simple polymorphism in Haskell. But feel free to correct me here.
Oh, they're typesafe (except for a bug in the implementation found a couple of years ago) but I agree they're more confusing than in languages without subtyping. I'd still pick Java over Haskell any day (but I'd take Haskell over Scala). Pick your poison, I guess.
> What a language gives you is less important that what it makes easy, and I cannot imagine a more cumbersome syntax for ADTs than the one in the linked proposal.
Nah, the syntax is fine. Somewhat more verbose than ML's or Haskell's, but it fits well with the rest of the language. So instead of Haskell's,
data Expr = ConstantExpr Int
| PlusExpr Expr Expr
| TimesExpr Expr Expr
| NegExpr Expr
deriving (Show, Eq);
You write,
sealed interface Expr {}
record ConstantExpr(int i) implements Expr {}
record PlusExpr(Expr a, Expr b) implements Expr {}
record TimesExpr(Expr a, Expr b) implements Expr {}
record NegExpr(Expr e) implements Expr {}
Not quite as succinct, but it's not really any more tedious (and you get component names, too).
Yeah, I guess I overreacted to the verbosity — it's definitely a huge improvement over the current state of Java. But is there a reason not to add NonNull annotations to the fields of type Expr?
It’s much more common nowadays to have SpotBugs/Checkstyle treat everything as non-null by default. Then you use Optional where necessary (or maybe @Nullable).
Also given that is one of the few languages that can speak fluently with technologies that are not very well known anymore, but still rocking many boats like SOAP webservices or AS400 mainframes
The bulk of the Java applications are inside banks and insurance companies
> are code organisation and tooling support (refactoring, code completion).
Agree.
Even though code completion has never been a problem for me in the past 20 years, not even with bash lately
If you're talking about programming style, I don't see the resemblance (have you seen COBOL code?), and if you're talking about usage, then Java is much more popular and used in many more domains than COBOL ever was. If you must compare it to anything, then the C of large server-side software would be a more apt comparison, I think.
> The bulk of the Java applications are inside banks and insurance companies
And Apple and Google and Netflix and Amazon and Alibaba and governments and militaries and telcos and cedit card companies
and airports and power plants and factories; wherever you'd find big, mission critical server apps, really.
> Java is much more popular and used in many more domains than COBOL ever was
It was merely a comparison on the number of line codes deployed that never changed over decades and nobody wants to touch anymore because they drive critical systems, that move a lot of money
The same reason why much of the COBOL in existence is still around
I wasn't comparing the capabilities or the qualities of the two
> And Apple and Google and Netflix and Amazon and Alibaba and governments and militaries and telcos and cedit card companies and airports and power plants and factories
Then C is definitely a better comparison. Code like that exists in huge quantities in any popular language used to write long-lived software for more than a couple of decades, but COBOL wasn't really such a language, like C and Java are. It was used a lot in some rather narrow domains and then it faded. It became popular in the late sixties, and by the mid eighties it was already falling out of fashion and became very niche. It barely had twenty years of dominance. If you insist, then a more modern language with a trajectory similar to COBOL would probably be VB.
> They rely on COBOL code too...
And quite possibly VB, too. But those companies write much of their new software in Java. They don't do it in COBOL (or in VB).
The same code from 20 or 30 years ago compiles today with little or no modifications
Try to run a servlet from 1998 or a struts web app from 2001 with a recent JVM
And yet you still find them in a lot of places, that you don't see, because you don't work with them, but that probably manage some of the transactions you make
They are legacy because they are being maintained for clientst hat have been using them for at least 2 decades and are virtually untouchable, but are still being updated, slowly, to keep them running
I'm not insisting, it's what it is.
VB is not legacy, VB is dead
No large company ever relied on VB to keep going
__ever__
COBOL is still being developed, because it's still used
To the point that COBOL can interface to Java or C# because companies prefer to update thei COBOL programs to call outside than rewrite them
The final approved ISO (of Object oriented COBOL) standard was approved and published in late 2002.
It's easier to run (and even revive) a 25-year-old applet than a 25-year-old OS/2 C application. Java has a much better backward compatibility story than C because C relies so heavily on OSes, many of which are effectively defunct.
Still, there are probably billions of legacy lines of code in C, C++ and Java, and hundreds of millions of lines of code in those languages are still being written every year (in Java more than in C/C++). In fact, more new lines of code are professionally written in new Java codebases than any other language with the possible exceptions of JS and Python (although probably not).
Like COBOL, existing VB code is still maintained, but very little new code is written. I'm not saying VB is exactly like COBOL, but I don't see any resemblance between Java and COBOL any more than I would between C and COBOL or Python and COBOL.
> It's easier to run (and even revive) a 25-year-old applet than a 25-year-old OS/2 C application
Are you sure?
Most of the APIs have been deprecated.
Builds for modern systems (64 bit) are non existent.
OS/2 has been dead for 20 years and there isn't much code being written for it anymore, I remember the Italian train company using OS/2 terminals, they have been dismissed more than a decade ago because IBM ended support for it.
Ironically you can run OS/2 in your browser, but not Java applets.
Now, to explain you what I mean when I say old Java code is as legacy as COBOL I will start with a story: it took Github a year and a half to upgrade from Rails 3.2 to Rails 5.2, on a less than 10 years old code base, to some of the best Ruby/Rails experts in the World.
Imagine that there are services that government agencies use, written 20 years ago in Java, by average former COBOL programmers that wanted to try new things, that will not be rewritten soon, and if they will it will take years for them to be adopted, that are interfacing with even older code running on mainframes.
Management bought the story that Java programmers were easy to find (they still are), being a Virtual Machine it would run easily (write once, run everywhere) and that was Enterprise (it was in the name).
It wasn't completely true.
The path Oracle pushed Java to make it compelling for new generations of programmers left behind a lot of already written and deployed code that can't be run directly on modern systems, can't be touched 'cause companies rely on that code and even if it could be upgrade there are no Java programmers that wants/are able to do it (it doesn't boost your career to work on it) if the hardware won't fail in the meantime.
2000 Java code is harder to write/maintain/upgrade for a Java programmer of 2020 than 2000 COBOL was for a COBOL programmer of the 70s.
In 5-10 years, when the first generation of early Java adopters will retire, there will be billions of lines of Java code that nobody will know how to keep running.
To coin an old programming phrase "The determined Real Programmer can write COBOL programs in any language"
Most of Java 1.0 is not deprecated, and runs unchanged today. Also, deprecated doesn't mean removed. The browser plugin is no longer developed and is not supported by contemporary browsers, but it's easy to turn an applet into a desktop app that runs on the latest version of Java (the Applet classes are still shipped with JDK 15, you can still compile that code, and you can still run it if you wrap it with some desktop runner).
> OS/2 has been dead for 20 years and there isn't much code being written for it anymore
You're missing the point. A lot of C code out there targets platforms like that. It is much harder to maintain than Java code.
> Ironically you can run OS/2 in your browser, but not Java applets.
> The path Oracle pushed Java to make it compelling for new generations of programmers left behind a lot of already written and deployed code that can't be run directly on modern systems, can't be touched 'cause companies rely on that code and even if it could be upgrade there are no Java programmers that wants/are able to do it (it doesn't boost your career to work on it) if the hardware won't fail in the meantime.
Except this is more true for C and C++ than for Java, and I still don't see the connection with COBOL. It's easier to run old Java code than old C/C++ code because the compatibility is so much better.
> 2000 Java code is harder to write/maintain/upgrade for a Java programmer of 2020 than 2000 COBOL was for a COBOL programmer of the 70s.
I don't know if that's true or not, but I do know that 2000 Java code is much easier to maintain than 20-year-old C/C++ code. Seems like you're not familiar with legacy C/C++: the situation there is much worse. I've seen systems running on ancient hardware because the C software was written for OS/2 or a particular version of the AIX compiler that comes with an AIX version that doesn't run on more modern hardware. I don't think there's any language with a better situation than Java when it comes to old codebases.
> Like a lot of Java code targeting Android is harder to maintain than C++, after just 6 months or depending on the brand of phone it runs on...
Android isn't Java, and it's never been. It's an incompatible fork that has never conformed to the Java specification of parts of an old version of Java. Its compatibility story might be very different from Java. It is also much smaller in its reach than Java, and even of COBOL, and its domain is also much smaller than either.
> Java is an extremely poor example of a helpful type system
My point exactly!
Most of them are.
Java is not special in this regard.
C? bad
COBOL? bad
C++? bad
Pascal? bad
Rust? better, but somewhat confusing
Go? not particularly good, but at least it's very simple
C#? same defects Java has
etc. etc.
Statically typed languages IMO are like turbo charged engines, if you are an expert driver you could go way faster, granted the road is in good shape, but if you are not, you'll crash, possibly in a horrible way.
> The fact that a statically typed program compiles gives you important assurances - especially post-refactor.
The only assurance in most of the statically typed languages is that code compiles, not that it works.
How about OCaml, Haskell, Scala, or F#? All have pretty decent type systems, with Scala and Haskell even supporting higher kinded types.
I'm at the point where I refuse to write production code in a language that doesn't have an expressive type system. Dynamically typed languages are even worse.
Have you considered maybe your problem is simply that you don't understand Scala?
I used to be a professional Scala dev and loved the language. Sure, there's some complexity, but I still strongly believe it is the most powerful and expressive static language around.
I know Scala is complex. Many languages are. No language starts out with the goal of being complex. They all want to be simple and elegant but the clash with real-world use-cases makes them complex. Like Bjarne Stroustrup said–there are languages that people complain about and there are languages that no one uses.
Seeing your messages, I really think you don't mean the same things as the others when you say "strong type system".
Generally what people here mean by strong type system is
All those tools are made to help the programmer write better, safer programs more easily, as well as lay out his thought
It is generally associated with FP, and are fond in languages such as Rust, Ocaml, Typescript, Haskell, F#
From what your examples are ( C, java, C#...) and the drawbacks you see (too much getters -> linked to an OOP style of programming), what you mean by "strong type systems" looks like it is the old C-style type systems (+ OOP though I don't really get what oop has to do with type systems). These systems are not mainly intended to help the programmer but are really meant ro help the compiler.
When in C you write
`int a;`
What you're doing is indicating to the compiler that for operations involving variable a, it should use the machine instructions for operation on integer (you can replace C with java and machine with jvm...).
These are necessary in order to have low-level control, but are not really hepful (apart from, maybe, documentation purposes. It is always useful to know that that ipv4 variable is a 24-bit int and not a string...)
These two types of systems are tremendously different things. I can really understand that you don't like static type systems if you only know the second type of system, which basically only adds constraints.
I think you should take a look at ocaml, or perhaps haskell, it would probably expand your horizons
Java is an extremely poor example of a helpful type system. Consider OCaml, Haskell, Elm, and others which avoid much of the verbosity you describe.
Static typing is really helpful when doing refactoring. The fact that a statically typed program compiles gives you important assurances - especially post-refactor. It's not a silver bullet but it's also certainly not "playing tennis with the compiler" as you describe.