Hacker News new | past | comments | ask | show | jobs | submit login

Off-topic but about Java generally:

Java is such a storied and long-running and used-almost-everywhere language especially in Data Engineering (see all the Apache Data Eng projects like Calcite, Hudi, etc) but I just find it soooooo verbose and everything being a class and having to override things ugh .. it's all the things I hate about OOP in the forefront.




One of the goals of Project Amber [1][2] is to move the language towards a more data-oriented programming model. With Records, patterns, sealed classes, etc., it should feel much less verbose over time. And unrelated to your concern but addressing some of the learning overhead, see Paving the Onramp. [3]

[1] https://openjdk.org/projects/amber/

[2] https://inside.java/tag/amber

[3] https://openjdk.org/projects/amber/design-notes/on-ramp


Any word on when some of project amber features will come out of preview? I get excited each JVM release for some of those features, but it seems like most of the releases the preview count just gets bumped, and a few more get added to the preview holding pattern.


Text blocks, var, records, sealed classes, and pattern matching in instanceof have been out of preview for some time, but two more features -- record patterns (https://openjdk.org/jeps/440) and pattern matching in switch (https://openjdk.org/jeps/441) -- are about to come out of preview.


Is there any work to make records actually usable out of the box?

Things like copying or creating derived records are a huge pain (or slight pain with code generators) while other languages have solved this long ago (even JS and C#).



So...Scala?


Sure, but you could refer to the lineage of a dozen languages. Most of the world runs Java and evolving it takes care and consideration not to alienate a massive user base and ensuring that it evolves in the right way, not quick responses to fashions and trends.


Isn't there natural interop between Java and Scala? Why needlessly enlarge the language.


Scala is super complex, introduces breaking changes all the time, is super slow to compile, multi-language projects are also complex, and the decisions that are right for Scala may not be right for Java.


The "super complex" and "introduces breaking changes all the time" comments are unsubstantiated FUD. Scala has evolved a lot in the last few years, particularly in the area of binary compatibility. It's a wonderful language and I can only recommend others try it. This from a programmer very happy with Scala.


And this is from a programmer that is not happy with Scala. Every single time I've upgraded the compiler there is a breaking change. They don't strictly follow semver. Most recently upgrading from the 2.11 to 2.13 compiler they made breaking serial version uid changes (I know don't use java serialization, but that wasn't my decision) and none of it was noted in the release notes.

When it comes to super complex just look at any of the type signatures of the standard library for collections:

   def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[IndexedSeq[A], B, That]): That 
Comparing this to Java it is "super complex". IntelliJ can't even figure out the types sometimes.


Scala 3 came out not too long ago and it fixed plenty of shortcomings. I do recommend giving it one another try.

Also, the reason why Scala’s collection has such complex signatures is because it is hands down the best collection lib out of any language I have used.


Nah the language is dead to me. And for petty reasons I don’t like significant white space. I only use it now because of work.


It still supports the older brace-style as well, doesn’t it?


Right and I don’t want to have to deal with half the community being split. Or half my coworkers doing it one way. These are just things I don’t want to deal with. I said my reasons were petty! But they’re my reasons.


Absolutely.


I don't know about the serialization issue but I don't doubt you had it.

> def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[IndexedSeq[A], B, That]): That

I should point out that this is the Scala 2.12 and and earlier signature. `CanBuildFrom` is gone from the Scala collections since Scala 2.13. In fact, the collections were redesigned for Scala 2.13 primarily to simplify method signatures, following community feedback.


And then when a dependency of one of your dependencies is broken agains the latest version. I know some of this has been cleaned up, but it is one of the main reasons I no longer use Scala - I have a rule about how long I'm willing to spend on build issues vs actually writing code, and Scala was always on the wrong side of that.

re: Complexity - At least the signatures for the core collections have been cleaned up a fair amount. That said, the richness of the type system and the prevalence of operator overloading always made it feel like a language you could be really productive in once you knew the language and the current codebase really well, but was really hard to just read through unfamiliar code and know what is going on.


> And then when a dependency of one of your dependencies is broken agains the latest version

How is this any worse than Java? My most vexing dependency-hell issues have involved breaking API changes to Hamcrest matchers and Apache Http Client; more recently Jackson-databind. All of those are Java libraries, brought in via transitive dependencies, usually from Java libraries.


Scala is also on the way out, adoption is steadily decreasing.


I'm not sure I would characterize it as "steadily". I think it's leveled off but I would agree it's not gaining any market share currently.


Yep, we’re migrating away from it at work too, too many problems, too slow to work with, and too much breaking.


I wish Scala leaned into being a Haskell-like (opinionated statically typed functional language) for the JVM rather than a kitchen sink.


There was definitely a large and vocal part of the community that wanted that, but I think early on there was a lot of tension between Scala being "better Java" and "Haskell for the JVM", and that probably hindered a lot of adoption.


Hmm I was thinking of learning Scala. Good to know it’s on the down trend.


I wouldn’t take these trends too seriously - scala is still huge, and the recent revamp (scala 3) might turn that “trend” around.

Also, learning a language with new idioms is always worth it, regardless of whether you end up using it.


Sure, but what about when you want to pull a Kotlin library into a Scala application? It works, but usually only works well if the library author limited themselves to the subset of the language that interops with Java (the language).

More features in Java (the language) gives other JVM languages a larger set of tools to design interop support around, while letting them remain a place for these features to incubate without the headache of the JEP. Sometimes these language-level changes may come with modifications to the JVM to support them as well, letting other languages clean up their implementations.

The whole situation works pretty well IMO.


Yes, and you can (via SBT) slowly introduce Scala into an existing Java codebase quite easily.


I wouldn't wish SBT on my worst enemies.


It’s terrible. But at least I rarely have to touch the config. I guess the silver lining is it’s so bad we don’t use it for anything besides dependency management so configs are simple and just copy pasted between projects and rarely touched.


A java project never uses sbt. Both maven and gradle have plugins for Scala.


Surely with GPT, it can't be that bad anymore ;p


We just updated our version and sometimes it'll get stuck in an infinite compile recursion loop. I dream of maven.


SBT is the worst thing about the Scala ecosystem. Just stick with Maven (or Gradle, if that's what you're using), enable the Scala plugin, and start trying Scala in more flexible leaf areas of your program (e.g. integration tests, ancillary tools, data migrations). See if it feels right for you.


Mixed compilation is absolutely terrible (slow) with Gradle, is it faster with SBT?


Very cool!


As the classic saying says: there are languages everyone complains about and languages that are not (actually) used. Verbosity is usually a _good_ think especially in large code bases with large number of people (where every successful startup will eventually get)


If verbosity would be a good thing Java wouldn't introduce language features/ library enhancements to cut down the noise (var, collection factories, switch expressions, records).


Those features are being released to please a larger set of people. People were relying on 3rd party libraries anyway for similar capabilities.


Java is verbose because it's inexpressive, not because it's good at documenting. It's Objective-C with everything too interesting removed, but they never added enough of it back.

Classic essay being http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom....


The only things left from Objective-C that actually matter are AOT (always available in commercial JDKs) and value types (Vahlhala will hopefully be ready some day).


The longstanding lack of generics (which has been remedied aside) who really complains about golang?

The reality is Java truly shows its age. Its dogmatic insistance on pure OOP and the enormous numbers of horrifyingly unintuitive design patterns adopted by the community cause even the most well intentioned engineering culture to eventually produce ugly codebases.

At this point if you're stuck in the JVM ecosystem you're almost certainly better off with Scala (which indeed is actually used) or the newer Kotlin.

In a way, for all the shit people give C++ modern C++ codebases are actually quite pleasant and the language is very flexible. Would I encourage its use for general production systems? Not really. That crowns is Golang's.


Come on, golang is as expressive as java 1.1. Java is much much less verbose and more readable than go, but for some reason the latter’s proponents can’t see it..


Go is great language, provided we went back in time and it was released in 1992.

As a rebranded Limbo with Oberon-2 method syntax in 2009, not so much.


I've returned to Java after using Clojure and Groovy for several years. I appreciate the fact that Java's just plain boring and slightly verbose.

Most of the time the complexity in my code has little to do with Java being verbose and more due to the business problem. There are areas to improve and Java's been making great strides recently. For example, in Java 21 we may finally have methods like getFirst() and getLast() for lists (via JEP 431) instead of the incredibly clunky list.get(list.size() - 1). Java also recently added multi-line Strings and templating is coming shortly. Streams and Optionals also reduce quite a bit of boilerplate, e.g. Optional's map and ifPresent methods are often elegant. Really I can't think of many other areas where Java gets in the way. Our team is incredibly productive with modern Java.

I think most developers actually write overly verbose code regardless of the language. And it seems little to do with years experience. This youtube channel covers most of the basics:

https://www.youtube.com/@CodeAesthetic

To me I just follow these recommendations naturally but in most PRs I review there's often huge amounts of overly nested code, poorly named methods, etc.


What do you miss from Clojure?

BTW, is that your channel?


Not my youtube channel. It just showed up in my recommended videos and it seemed like good advice (common sense). It's helpful to point devs to those videos when I see them making those types of mistakes.

I miss the data oriented approach Clojure libraries take. I remember having an issue with Ring and I just dove into the Ring source code and it was so simple and clear and I found the solution to my issue in minutes. I've never had that experience with Java and instead resort to forums, stackoverflow, etc. Most Java libraries would have several layers of abstraction and they're often intimidating. I consider myself an amateur Clojure dev and yet still contributed some PRs to some projects.

With that said, I've written some internal tools in Clojure and it was a nightmare whenever I had to modify them. They were pretty simple CLI tools that only needed updates every 6 months or so. I usually have to spin up the project with a repl just to understand the inputs and outputs to functions. I've ported all internal tools I created at my current company from Clojure to Java and I personally find them so much easier to maintain.


Going from Java 8 to Scala was mind melting. Would never want to go back. Though I’ve heard later versions of Java are better. And katlin seems like an in between.


Or stick to kotlin and keep the mind conveniently solid ;)

I was one of the Bored Scala Crowd in the audience of a presentation by jetbrains people that must have been not too long after 1.0, took me half a decade to accept that a "poor man's scala" is actually the language that I want.


I found just the opposite. Kotlin would rather add 10 special cases than one higher-order abstraction; I'd rather learn one slightly fancy concept than a laundry list of ad-hoc cases.


That's actually a quite accurate description of my own feelings. "Why emulate parts of scala on syntax level when you can have the real thing?". But that "real thing" is the one that drives people to lose themselves in cats vs scalaz debates and the like, there's clearly something in scala that causes a very strong "if you use it to write java without semicolons you're doing it wrong" undercurrent. "java without semicolons" kotlin isn't considered good either, but the distance from there to "kotlin as intended" isn't big at all.


Agreed!

Regardless of programming language, every substantial software development needs to make serious architectural choices, otherwise things will become messy. I learned this the hard in my first programming job out of university. We were a C/C++ shop doing distributed software and one question to decide right upfront is: shared memory vs message passing. Both have advantages and disadvantages, but don't mix well. We started out with message passing, but over time somebody added POSIX shared memory as a performance hack (which two processes happen to run on the same machine). Over time, we added a second, non-POSIX shared memory layer for performance reasons under Windows. It was an unmaintainable mess. The core problem was that the CTO didn't understand distributed programming well enough to push back against those performance hacks. "How do you handle software architectural leadership?" used to be one of my replies to the inevitable "have you got questions for us?" in job interviews, when I was being interviewed. Now that I am making architectural decisions myself, I put a lot of efforts into this, for example building suitable linters that flag violations in code reviews.

If your team fights over cats vs scalaz or over Scala-as-OO vs Scala-as-FP then that's a sign that the technical / architectural leadership is weak. Choices like pure-OO vs pure-FP vs mixing them require care, and are hard to change in-flight. If you have strong modularisation, you can successfully use different paradigms in different modules, but strong modularisation needs care and architectural discipline, too. Part of the problem is that the style of programming that libraries like cats require (monads, functors, applicative, type-classes, HKTs) is not yet widely understood. This approach to programming needs its 'map/reduce moment' and become part of the mainstream introduction-to-programming curriculum. We'll get there, maybe in about a decade.


Ya I’d love to give it a try. Probably will prioritize it for next job Switch.


Yea, I'd imagine comparing a 9 year old version of a language to another would be "mind melting". And you are comparing to Java 8, from before Java re-organized their JEP process to ship features far faster, with a different release philosophy and feature roadmap.

Kotlin is worth picking up, but after seeing the speed at which Kotlin moves compared to how Java moves now, I don't think Kotlin will keep up long term.


Much prefer Kotlin to Scala myself. Forcing monadic composition everywhere was a deal breaker for me. Same as the viral async problem in JS, imho.


(Unlike Haskell,) Scala does not force monadic composition on you at all. You can use Scala as a pure OO language, or for old-skool ML-like FP where you don't use monadic context abstraction. I've done both successfully in production. Indeed I strongly advise against a monadic programming style for programmers with a mainstream programming background (imperative and OO).

In my (considerable) experience of teaching programming, imperative programmers find jumping straight from imperative programmers to a monadic style extremely difficult, the more experienced, the more difficult.


Thankfully that there are people still writing Java to keep the JVM going for Scala users.


So your (general) complaints are all you do add to this when others try to create things to help others?


Agreed. Reading and writing Java code just really annoys me. It's so ugly, in my opinion.


Just for balance: after writing much Java years ago, then moving on to mostly JS/TS, Scala and Kotlin, going back and looking at old Java I forget writing, it looks very nice and easy to understand.


>> It's so ugly

> nice and easy to understand

Java is definitely more practical than pretty. This frustrates the trendy crowd, but I think its important for tools to be practical. Shiny, pretty languages are never as long-lived as practical "ugly" languages.


If it scares away the "let's rewrite it in language/framework of the day" crowd, that's a plus in my book.


I'm certainly not a member of the "trendy crowd." I say Java is ugly as a fan of Lisp and C. There's just so much boilerplate to implement something basic.


Just try something else.


And then you'll hear of it being "verbose" and "boring" too. Grass is always greener...


But at least you remove the doubt. And Java is a special case of objectively being browner.


You're not wrong. I've worked in prod with all the cool languages (Scala, Haskell, Rust, Go, etc...) but stick to Python/typeScript when I want to be pragmatic.




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

Search: