Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> 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).

[1]: https://cr.openjdk.java.net/~briangoetz/amber/datum.html


> With generics added 15 years ago,

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).


I'm guessing that at one point or another Java will get nullability types similar to Kotlin's.


> , Java is practically becoming an ML

For new code, yes.

For old code, it's more in the realm of COBOL

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


> it's more in the realm of COBOL

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.


> have you seen COBOL code?

A lot of it

Always stayed away from it

> 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

They rely on COBOL code too...

Believe me


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).


C is not legacy.

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.

https://www.pcjs.org/software/pcx86/sys/os2/ibm/1.0/

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"


> Are you sure?

Yes.

> Most of the APIs have been deprecated.

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.

You can run Java them (and desktop apps) the same way: https://www.leaningtech.com/pages/cheerpj.html

> 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.


> A lot of C code out there targets platforms like that. It is much harder to maintain than Java code.

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...

> You can run Java them (and desktop apps) the same way: https://www.leaningtech.com/pages/cheerpj.html

Cool


> 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.


The worst code I've ever seen in my life are Spark scripts written in Scala.

Scala is so complicated that people use only a fraction of its features, usually the simpler ones.

It takes a real commitment to become a prolific Scala programmer.

> Dynamically typed languages are even worse.

I don't comment on personal taste, everybody has their own.


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.


Have you considered maybe the problem is that I know Scala enough to know when it's bad?

(I studied Scala at EPFL with Martin Odersky as professor)


So, you've never seen production-grade Scala application code?


As I've already said here (https://news.ycombinator.com/item?id=24614064) there are people like you that assume that their background is the only background possible.

Scala is complex, writing production grade Scala requires skill not common, it is like asking regular commuters to only drive F1 cars.

Would everyone go faster or there would be more crashes?

Would you blame drivers for the crashes?


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

ADTs, inference, type-checking, pattern-matching...

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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: