it consistently works and has a huge ecosystem, but "beautiful" is never a word I would use to describe java. off the top of my head:
* no type level concept of a const object (ie, you can have a const reference to a List, but never a reference to a const list). this makes const-ness an implementation detail of the class itself! so frustrating that List:add() can throw depending on the underlying class.
* lack of tuples (and no, record doesn't count). this is just a syntactic sugar thing, but I really miss it from c++ and python.
* var is far less powerful than c++ auto.
in most cases, I actually prefer the syntax of c++, which is really saying something.
> The language itself is quite beautiful when used properly and with modern features.
I respect your opinion but I wouldn't call Java beautiful (of course it depends on your definition of beautiful). It takes so much ceremony to do things you would do without any thought in other languages .
Initiating a mutable set
Python
`a = {1,2}`
What most Java programmers do
```
var a = new HashSet<>();
a.add(1);
a.add(2);
```
Shorter one but requires more ceremony, and hence knowledge of more language semantics
```
var a = new HashSet<>(new Arraylist<>(List.of(1,2))
```
I don't know if the above works but the Idea is to initiate a list and pass it into a HashSet constructor.
Similarly Java 21 allows you to model union types but doing so requires you to define N+1 classes where N is the number of union cases whereas in other languages it's as simple as `type A = C |D`
> The language itself is quite beautiful when used properly and with modern features.
> It just really needs a makeover and better tools.
I love java, wouldn't call it beautiful though. But I don't need a language to be beautiful, I need it to be pragmatic, blisteringly fast, have an extensive ecosystem and top quality tooling. Java delivers #1 on all of those so I love it.
For beauty, I like ruby and lisp, but those both fail on all the other criteria so they are mostly for hobby use for me. (Python, the darling of everyone these days, is pretty much dead last on every criteria except popularity.)
> better tools
I'd say Java & JVM has pretty much the best tooling on all fronts.
I can't think of anything that has better tooling around the language and runtime.
I can't see why you'd pick Java over C#. IMO its basically all the same preferences with slightly more consistent syntax choices. That said, Java is great too. It's underrated considering what a workhorse it is.
I am a big functional programming geek. I am one of the few people on the planet who can honestly say I have been paid to write F#, Haskell, Clojure, and Erlang. I have spoken at FP conferences like six or seven times, and I have shit on Java for most of my career.
And yet, my latest talk at Lambda Days basically boiled down to “Java 21 and later don’t actually suck anymore”, and I genuinely do mean that.
Java 21 is actually fun to write, even for a grumpy FP advocate like me. Virtual threads make concurrency a lot simpler, and now that there’s proper records and ADTs (in the form of sealed interfaces), along with pattern matching, the language is actually pleasant to use. I haven’t dived into 25 yet, but I suspect I will like it as much or more than 21.
The biggest issue, though, is that Java programmers won’t use the new features. It was like pulling teeth at my last job to get people to use stuff from Java 8 (e.g. the `var` keyword), and none of my coworkers even knew how to use NIO or BlockingQueues which I think predate agriculture. I mean, hell, I had explain what “fairness” was to engineers when using a ReentrantLock because someone “corrected” my code with `synchronized`.
I don’t think Java makes people into bad programmers, but I do think it selection-biases for intellectually unambitious engineers. They learn exactly enough Java in college to pass their courses, and then get a job at a BigCo that doesn’t strictly require ever learning anything more than what they were taught in their “intro to data structures” course.
I have met some extremely intelligent Java engineers who do have intellectual curiosity, so I am not saying it affects everyone, but I do think that they are the minority. Java 25 might add every feature to make my wildest dream come true but it won’t matter if I am not allowed to use it.
> I don’t think Java makes people into bad programmers, but I do think it selection-biases for intellectually unambitious engineers. They learn exactly enough Java in college to pass their courses, and then get a job at a BigCo that doesn’t strictly require ever learning anything more than what they were taught in their “intro to data structures” course.
I think that's a fair comment, but also there's this perspective: I first touched Java 1.1 in 1997 in college, and only for a semester. Then for the next 22 years never looked at a line of Java, working mostly in C++ and Python plus dabbling in FORTRAN for high performance stuff that needed to be written there. I generally consider my self not intellectually unambitious.
Then I moved to a Java shop who specifically needed high performance math (well at least as high performance as you can get in Java, which is actually pretty good now). But we stick to Java 8 compatibility because we have some BIG customers who require that because of LTS on Java 8. There are some nice constructs that would help make the code more readable and modern, but when you need to support people and actually make money you do what you need to.
Programming language is a tool. Java developers value stability and ease of understanding for the code. I've seen the nice features you complain that don't get used, reality is that nobody wants to waste time knowing them unless they are intuitive to use. Especially when are forcing to use newer JDKs.
There is no value in solving a challenge in a way that only you understand or make others lose time trying to understand the logic.
Java 8 was the peak of development age for the JDK. Everything that came after isn't really memorable nor helpful, especially lambdas. You mention "var", why would we ever want in Java to hold a variable that you can't read immediately what is the type? That is a source of bugs and time waste to track down what object is being used.
I don't mind you are happy with all these changes, just remember that we absolutely don't care about them nor will make much of an effort because in the end of the day we don't want to follow the same route of other programming languages unable to handle gigantic and complex platform systems.
This isn't a competition to showoff who can apply new tricks, we absolutely don't care about functional programming. Java code must be simple and easy for anyone to read, that's it.
I view this largely as a symptom of the widescale “success” of the bloated J2EE app servers in the early 2000s to mid 2010s. Your Java version and dependencies were locked in and upgrading was a massive effort. A large group of developers stagnated on Java 1.4.2 and 5 and seemingly never updated their use of the language, even when moving to Java 8 and beyond. The legacy stuff keeps ticking along.
Yeah, people often underestimate the importance of community when they discuss programming language. In fairness to the Java crowd, you rarely see codebases looking like the team was trying to fit every new concept from some blog they read somewhere in the codebase, like you do in e.g. Scala or Haskell.
- how’s the environment? Build tools, dependency management, etc. it used to be a PitA back then.
- how has the typing system and generics evolved to support this? Have they introduced any type of variance?
The explanation on why Java lets you use unnamed variables to prevent accidental use during deconstruction, but those unusuable variables still getting initialized by calling accessors, is a perfect example why I dislike the way Java implements improvements.
Every single, logical step that led to this hidden performance problem makes complete sense, because every improvement had to be its own tiny, contained improvement, but the end result is that `case Foo(int _, String _, User _, int age)` will still call three getters _just in case_ you're abusing the language to add side effects to accessors.
Perhaps even worse is the explanation that follows: if you don't mess up your accessors, the JVM _may_ decide to not call those accessors at runtime. So now the language itself has this weird performance impact to maintain backwards compatibility, but at runtime that backwards compatibility _may_ not exist and provide you with a performance improvement instead, negating the whole reason why backwards compatibility was added in the first place.
I like the improvements to Java, don't get me wrong. It's no longer the JDK 1.7 language poor enterprise programmers are stuck with. But if the Java people had come together and worked this out as one single feature, rather than five different ones, we wouldn't have needed to remember edge cases/a code analysis tool to remind us that using this intuitive language feature _may_ actually has a 3x performance impact depending on the mood the JVM is in today.
I’ve worked in Java for over 20 years. Being the “lingua franca” of the enterprise is its biggest strength IMO, but it is also perplexing to me that it was able to do that in the first place. The language itself is not bad. The tooling around it is very good. But the codebases you encounter written in it, particularly in the enterprise, are often horrible.
Mind sharing why do you consider Java tooling to be good (and largely, what is good here)?
The reason I ask is that I recently had to join a Java project at my company, and having a background in Node/Rust/Perl/Lua and some C++, I found the Java tooling to be extremely unsuitable for my taste.
A simple example: there is no standard LSP server, and the amount of jumps required to have a working setup with FOSS tools and make it IDE-independent is just horrendous. In every other ecosystem I've worked with so far, it was pretty easy in the last 5 years: if you don't like IDEs, you can keep using your vim/emacs/helix or whatever and just embed a plugin or two, with LSP integrated -- and you're ready to go.
Java world felt complete the opposite, like you had to use/buy some commercial tools to start doing something.
i would prefer it, if they improve and extend the java standard library and the tooling for libraries
many people will tell you that the standard library is not as performant as it could be and does not have as many batteries as python and try managing your dependencies...
that would be far more important than the next super duper feature IMHO.
Almondsetat|5 months ago
jorrdang|5 months ago
JEP 395: Records: https://openjdk.org/jeps/395
JEP 440: Record Patterns: https://openjdk.org/jeps/440
JEP 394: Pattern Matching for Instanceof: https://openjdk.org/jeps/394
JEP 441: Pattern Matching for Switch: https://openjdk.org/jeps/441
JEP 409: Sealed Classes: https://openjdk.org/jeps/409
JEP 361: Switch Expressions: https://openjdk.org/jeps/361
JEP 456: Unnamed Variables & Patterns: https://openjdk.org/jeps/456
JEP 507: Primitive Types in Patterns, instanceof and switch (Third Preview): https://openjdk.org/jeps/507
JEP 512: Compact Source Files and Instance Main Methods: https://openjdk.org/jeps/512
JEP 458: Launch Multi-File Source-Code Programs: https://openjdk.org/jeps/458
JEP 511: Module Import Declarations: https://openjdk.org/jeps/511
JEP 502: Stable Values (Preview): https://openjdk.org/jeps/502
JEP 513: Flexible Constructor Bodies: https://openjdk.org/jeps/513
unknown|5 months ago
[deleted]
brap|5 months ago
There were times I hated it, but turns out I really just hated messy, over-engineered legacy code and working in a gray cubicle at aging MegaCorps.
The language itself is quite beautiful when used properly and with modern features.
It just really needs a makeover and better tools.
leetcrew|5 months ago
* no type level concept of a const object (ie, you can have a const reference to a List, but never a reference to a const list). this makes const-ness an implementation detail of the class itself! so frustrating that List:add() can throw depending on the underlying class.
* lack of tuples (and no, record doesn't count). this is just a syntactic sugar thing, but I really miss it from c++ and python.
* var is far less powerful than c++ auto.
in most cases, I actually prefer the syntax of c++, which is really saying something.
akkad33|5 months ago
I respect your opinion but I wouldn't call Java beautiful (of course it depends on your definition of beautiful). It takes so much ceremony to do things you would do without any thought in other languages .
Initiating a mutable set
Python
`a = {1,2}`
What most Java programmers do
``` var a = new HashSet<>(); a.add(1); a.add(2); ```
Shorter one but requires more ceremony, and hence knowledge of more language semantics
``` var a = new HashSet<>(new Arraylist<>(List.of(1,2)) ```
I don't know if the above works but the Idea is to initiate a list and pass it into a HashSet constructor.
Similarly Java 21 allows you to model union types but doing so requires you to define N+1 classes where N is the number of union cases whereas in other languages it's as simple as `type A = C |D`
jjav|5 months ago
> It just really needs a makeover and better tools.
I love java, wouldn't call it beautiful though. But I don't need a language to be beautiful, I need it to be pragmatic, blisteringly fast, have an extensive ecosystem and top quality tooling. Java delivers #1 on all of those so I love it.
For beauty, I like ruby and lisp, but those both fail on all the other criteria so they are mostly for hobby use for me. (Python, the darling of everyone these days, is pretty much dead last on every criteria except popularity.)
> better tools
I'd say Java & JVM has pretty much the best tooling on all fronts.
I can't think of anything that has better tooling around the language and runtime.
thevillagechief|5 months ago
jayd16|5 months ago
LelouBil|5 months ago
tombert|5 months ago
And yet, my latest talk at Lambda Days basically boiled down to “Java 21 and later don’t actually suck anymore”, and I genuinely do mean that.
Java 21 is actually fun to write, even for a grumpy FP advocate like me. Virtual threads make concurrency a lot simpler, and now that there’s proper records and ADTs (in the form of sealed interfaces), along with pattern matching, the language is actually pleasant to use. I haven’t dived into 25 yet, but I suspect I will like it as much or more than 21.
The biggest issue, though, is that Java programmers won’t use the new features. It was like pulling teeth at my last job to get people to use stuff from Java 8 (e.g. the `var` keyword), and none of my coworkers even knew how to use NIO or BlockingQueues which I think predate agriculture. I mean, hell, I had explain what “fairness” was to engineers when using a ReentrantLock because someone “corrected” my code with `synchronized`.
I don’t think Java makes people into bad programmers, but I do think it selection-biases for intellectually unambitious engineers. They learn exactly enough Java in college to pass their courses, and then get a job at a BigCo that doesn’t strictly require ever learning anything more than what they were taught in their “intro to data structures” course.
I have met some extremely intelligent Java engineers who do have intellectual curiosity, so I am not saying it affects everyone, but I do think that they are the minority. Java 25 might add every feature to make my wildest dream come true but it won’t matter if I am not allowed to use it.
michaelrpeskin|5 months ago
I think that's a fair comment, but also there's this perspective: I first touched Java 1.1 in 1997 in college, and only for a semester. Then for the next 22 years never looked at a line of Java, working mostly in C++ and Python plus dabbling in FORTRAN for high performance stuff that needed to be written there. I generally consider my self not intellectually unambitious.
Then I moved to a Java shop who specifically needed high performance math (well at least as high performance as you can get in Java, which is actually pretty good now). But we stick to Java 8 compatibility because we have some BIG customers who require that because of LTS on Java 8. There are some nice constructs that would help make the code more readable and modern, but when you need to support people and actually make money you do what you need to.
nunobrito|5 months ago
There is no value in solving a challenge in a way that only you understand or make others lose time trying to understand the logic.
Java 8 was the peak of development age for the JDK. Everything that came after isn't really memorable nor helpful, especially lambdas. You mention "var", why would we ever want in Java to hold a variable that you can't read immediately what is the type? That is a source of bugs and time waste to track down what object is being used.
I don't mind you are happy with all these changes, just remember that we absolutely don't care about them nor will make much of an effort because in the end of the day we don't want to follow the same route of other programming languages unable to handle gigantic and complex platform systems.
This isn't a competition to showoff who can apply new tricks, we absolutely don't care about functional programming. Java code must be simple and easy for anyone to read, that's it.
plasma_beam|5 months ago
pyrale|5 months ago
latchkey|5 months ago
My old CTO boss swore he wouldn't ever use annotations because they were too much magic for him.
"No! Writing out gobs of XML to configure Spring DI is the only way!"
whobre|5 months ago
santiagobasulto|5 months ago
- how’s the environment? Build tools, dependency management, etc. it used to be a PitA back then. - how has the typing system and generics evolved to support this? Have they introduced any type of variance?
Xenoamorphous|5 months ago
golyi|5 months ago
jeroenhd|5 months ago
Every single, logical step that led to this hidden performance problem makes complete sense, because every improvement had to be its own tiny, contained improvement, but the end result is that `case Foo(int _, String _, User _, int age)` will still call three getters _just in case_ you're abusing the language to add side effects to accessors.
Perhaps even worse is the explanation that follows: if you don't mess up your accessors, the JVM _may_ decide to not call those accessors at runtime. So now the language itself has this weird performance impact to maintain backwards compatibility, but at runtime that backwards compatibility _may_ not exist and provide you with a performance improvement instead, negating the whole reason why backwards compatibility was added in the first place.
I like the improvements to Java, don't get me wrong. It's no longer the JDK 1.7 language poor enterprise programmers are stuck with. But if the Java people had come together and worked this out as one single feature, rather than five different ones, we wouldn't have needed to remember edge cases/a code analysis tool to remind us that using this intuitive language feature _may_ actually has a 3x performance impact depending on the mood the JVM is in today.
unknown|5 months ago
[deleted]
mberning|5 months ago
k0tan32|5 months ago
The reason I ask is that I recently had to join a Java project at my company, and having a background in Node/Rust/Perl/Lua and some C++, I found the Java tooling to be extremely unsuitable for my taste.
A simple example: there is no standard LSP server, and the amount of jumps required to have a working setup with FOSS tools and make it IDE-independent is just horrendous. In every other ecosystem I've worked with so far, it was pretty easy in the last 5 years: if you don't like IDEs, you can keep using your vim/emacs/helix or whatever and just embed a plugin or two, with LSP integrated -- and you're ready to go.
Java world felt complete the opposite, like you had to use/buy some commercial tools to start doing something.
kasperni|5 months ago
Not sure they are worse than other languages?
bullen|5 months ago
ivanjermakov|5 months ago
deknos|5 months ago
many people will tell you that the standard library is not as performant as it could be and does not have as many batteries as python and try managing your dependencies...
that would be far more important than the next super duper feature IMHO.
kasperni|5 months ago
such as?
eweise|5 months ago
vips7L|5 months ago
truth_seeker|5 months ago
akkad33|5 months ago
rafram|5 months ago
vbezhenar|5 months ago