Java sealed classes and exhaustive pattern matching (neilmadden.blog)

116 points by hnisjafx40 7 hours ago

shepherdjerred 3 hours ago

I love how far Java has come. I still prefer TypeScript since I do a lot of frontend work and prefer to use the same language across the stack.

With the said, you can do exhaustive pattern matching in TypeScript! https://github.com/gvergnaud/ts-pattern

ngruhn an hour ago

Isn't that overkill? You can check exhaustiveness with a trivial little helper:

    function exhaustive(witness: never): never {
      return witness
    }
https://www.typescriptlang.org/play/?#code/FAFwngDgpgBAKgZQB...

whilenot-dev 14 minutes ago

Agree, python calls this little helper assert_never[0]. I opened an PR to add it to the TypeScript docs some time ago: https://github.com/microsoft/TypeScript-Website/pull/3599

[0]: https://docs.python.org/3/library/typing.html#typing.assert_...

n_e 6 minutes ago

In the example you don't even need the default clause and the helper (the error message without it is worse though).

wk_end an hour ago

You don't need a library for this; the idiomatic approach is to lean on TypeScript's narrowing and native control flow (ifs and switches, or maybe IIFEs), along with (maybe) the never type to enforce exhaustiveness.

https://www.typescriptlang.org/play/?jsx=4#code/JYWwDg9gTgLg...

I guess the library is slightly nicer, arguably, but I don't think it's worth the external dependency and added complexity.

armchairhacker 6 hours ago

Java also has recursive patterns and (maybe still in preview) literal patterns: `switch (x) { case A(B(true, var c)) -> f(c); }`

timshel2 5 hours ago

Scala punching the air rn

mlinksva an hour ago

No affiliation with either, but I don't think Java and Scala are punching at each other, and they're both doing great. Needless to say Java has continued to exceed expectations and given its huge role in the world, that's worth [handwave very huge number] in consumer welfare. Scala has evolved the last several years to again become perhaps the most interesting big-ish application language, eg see Odersky's recent https://scaladays.org/session/opening-session-keynote/ and https://dl.acm.org/doi/10.1145/3786335.3813127

AdrenalinMd 4 hours ago

I still write Scala. But not sure for how long. I swear, it's such a joy to write code in Scala.

It's like French poetry.. So much elegance. An no effect system BS. Just like Martin Odersky intended it to be!

therealdrag0 8 minutes ago

Agree. Really enjoy it—without type effects libs.

theanonymousone 3 hours ago

>it's such a joy to write code in Scala.

Yes, but also a bit of a torture to read code in it..

tentacleuno 3 hours ago

Curious what you meant about the effect system BS?

jmalicki 2 hours ago

dozerly 4 hours ago

Sigh, I so very miss writing Scala.

panny an hour ago

I don't think you need those switch defaults with the sealed types. I didn't check with a compiler, but I think those are unnecessary.

thfuran 33 minutes ago

The switches with defaults are both switching over a String with only literal cases. That can't be exhaustive without a default, and switch expressions must be exhaustive.

Larrikin 6 hours ago

Java continues to try and catch up to Kotlin https://kotlinlang.org/docs/sealed-classes.html

I didn't mind Java when the comparisons were to C++, Ruby, and Python. I can not find a reason to go back after Scala (which seemed to fail due to being indiscriminate) and especially Kotlin

pron 5 hours ago

A hoarder may have much more furniture than I do, but if I buy a sofa it doesn't mean I'm trying to catch up to the hoarder (who has five). Java isn't trying to catch up for the simple reason that we don't want it to have all the features Kotlin does; in fact, we're trying very hard to avoid that (not to mention that we have yet to adopt a single Kotlin feature; our features usually take a different form, even though Kotlin, Java, and many other languages often rely on the same inspiration, which is usually the ML language). That's because some languages aim to be feature-rich while others aim to be more minimal. Both are likely to accumulate features over time, but at very different rates (we'll hold off on features for years until we're satisfied that their value justifies the added complexity to the language, as keeping that relatively low is very important to us).

If you like a richer language, the Java platform offers you options, but many people prefer smaller languages (the number of Java Platform developers who use the Java language has remained pretty much at a constant ~90% for the past 15 or more years), but we're aware that a non-tiny minority of developers prefer richer languages, and so we accommodate them, too. Either way, 95% of the JDK is runtime (standard library and the JVM) and tooling, and you'll enjoy it regardless of which frontend language you prefer.

fallingbananna 2 hours ago

The analogy is very sensible, but I would like to add that Kotlin isn't really hoardning features in the same way Scala did.

Compared to Scala, C++, or even Typescript and C#, Kotlin feels a like a well thought out minimal modern language (as minimal as you can be, while still providing conviniences that we have grown to expect like nullability checks, or data classes).

(*Except coroutines, I feel like Java is achieving that goal waaay better with virtual threads and structured concurrency than Kotlin did with "forever experimental" API that is full of footguns and lacks any observability.)

gf000 an hour ago

derriz 2 hours ago

speed_spread 27 minutes ago

CrimsonRain 2 hours ago

You're driving java feature set with great expertise. It is hard to complain about it.

I know it is not a technically marvelous thing, it's not a high priority either...but the only thing I'd want differently is lot more syntactic sugar that reduces common boilerplates/actions/patterns to simple one liners.

However, with AI writing most of the code now, I now doubt the importance.

bmacho 4 hours ago

> Both are likely to accumulate features over time, but at very different rates (we'll hold off on features for years until we're satisfied that their value justifies the added complexity to the language, as keeping that relatively low is very important to us).

This strategy will still navigate Java into a random local optimum like it happened with other languages (that value backward compatibility), just more slowly. The greedy algorithm does that. Even if you do it slowly and you are extra careful that each step indeed betters the language.

pron 3 hours ago

valzam 4 hours ago

oldsecondhand 3 hours ago

throwaway7783 2 hours ago

troupo 2 hours ago

> A hoarder may have much more furniture than I do, but if I buy a sofa it doesn't mean I'm trying to catch up to the hoarder

A few years back the same argument was phrased as "we don't adopt features from lesser languages" or something to that effect. Since then Java has been busy adopting those features at an accelerated pace.

> If you like a richer language, the Java platform offers you options, but many people prefer smaller languages

And Java is no longer a smaller language. Because artificial purity for misguided reasons hurts the language. And thankfully most people in Java have finally realized it.

pron an hour ago

dtech 4 hours ago

> not to mention that we have yet to adopt a single Kotlin feature; our features usually take a different form, even though Kotlin, Java, and many other languages often rely on the same inspiration, which is usually the ML language

This seems disingenuous at best, or it's a symptom that I've noticed as a user more often that your JDK team seems to have blinders on and dismisses/ignores most other languages even if feature have proven themselves 10 times over.

There's several features Java added or is trying to add, usually 5-10+ years later than Kotlin, and that's ignoring Scala:

* Local type inference

* Switch expressions

* Records, although I found them barely usable because there is no copy() method or with-ers

* String templates unsuccessfully

* A very stripped down version of smart-casting with switch pattern matching

I'm sure there's tech-debt and esoteric compatibility concerns which make evolving Java hard, but from a developer's perspective it's just glacial to evolve and the result is weaksauce.

pron 3 hours ago

throwaway7783 2 hours ago

DarkNova6 5 hours ago

What I like about Java is that it is a deliberate late-mover language. It doesn't go for the latest shiny thing but looks at what features have proven themselves in other languages.

I can't help but to be a little sobered by the promises of Kotlin and C#. They look great on the surface, but once you have more complicated code to work on they tend to show warts quite fast.

Java is remarkably consistent and really doesn't have any sharp edges. Even with generics and type erasure, I found myself fighting the language semantics in C# way more often than Java.

jayd16 4 hours ago

> I found myself fighting the language semantics in C# way more often than Java

What's an example? I find C# quite well designed despite the Chinese menu of features.

> Java is remarkably consistent and really doesn't have any sharp edges. Even with generics and type erasure [...]

These back to back with a straight face...What is a sharp edge in your mind?

arein3 4 hours ago

cogman10 5 hours ago

I personally enjoy Kotlin. There are potential warts with it, but those exist with other languages.

That said, Java taking it's time and observing the playing field is a huge benefit. And now that they've been slowly delivering new language features, it's really made it pretty nice flow of powerful well thought out extensions each release. There hasn't been one of the new features that I think missed the mark.

biglyburrito 2 hours ago

Java lacks a ton of quality-of-life features that are table stakes in other languages, including C# and Kotlin. Auto-properties, async, extension methods, nullable reference types, primitive types, string interpolation/templates -- Java is inferior to C# in every one of these areas.

biglyburrito 5 hours ago

Java still inexplicably doesn't have first-class support for string interpolation/templates. They were slated to add it in Java 23, but they removed it from the preview and it hasn't been seen since.

https://www.happycoders.eu/java/string-templates/

pjmlp 5 hours ago

Because the feedback on how they worked apparently wasn't that positive.

Also who cares having to use String.format() in the agentic coding age?

whartung an hour ago

kbenson 4 hours ago

mystifyingpoi 3 hours ago

sthuck 4 hours ago

I would definitely trim like 20% off scala, but I think slow compile times were the main reason. To a much lesser degree but sbt being one of the first things you deal with when learning the language didn't help.

If you put a gun to my head and tell me you can't write in kotlin, you must choose either Java or Scala - for a small project I think I choose modern Java. If you tell me I need to choose for a large cross team and mission critical project - I think I take the bullet.

Still, I have a soft spot in my heart for scala, learned a lot from it.

jmarlow47 5 hours ago

Kotlin feels like it's having an identity crisis. The gap between the two languages continues to decrease. Kotlin is trying to be server-side, Android, but also every other platform (KMP). Feels like everything is brand new and also deprecated at the same time, always moving on to something new.

Maybe Roman really was the soul and it lost its touch without him?

I guess in the age of AI it doesn't matter since a few years from now, if you change your mind, you can just ask Jeeves to one-shot rewrite it back to Java.

jeroenhd 4 hours ago

Until Java fixes its type system to add nullable types (and not in that ridiculous tri-state nullability method that one JEP proposes), Kotlin will be several steps ahead of Java.

I can speak from experience that Fable 5.1 still writes code that compiles and usually runs fine but throws null pointer exceptions in reasonable edge cases.

arein3 4 hours ago

jmarlow47 2 hours ago

14u2c 4 hours ago

This comment has major 2018 vibes. Most enterprises I know have have migrated back to mainline Java. We'll see if this changes again LLM era, now that prioritizing the talent pool is less important and the friction of migrating stacks is much reduced.

sideeffffect 6 hours ago

> Java continues to try and catch up to Kotlin

Does it, really? Java has had pattern matching since 21 (2023). Kotlin still, to this day, the year of our Lord 2026, doesn't...

tancop 4 hours ago

Kotlin had it since 1.0, it's just called `when` instead of `match`.

https://kotlinlang.org/docs/control-flow.html#expressions

wiseowise 2 hours ago

za3faran 3 hours ago

dtech 4 hours ago

Kotlin has always had smart-casting in if and when (sort of switch) expressions, which are strictly more powerful than the current version of Java "pattern matching". Both don't do de-structuring which I would consider a basic requirement for pattern matching, but at least Kotlin didn't call it pattern matching.

pjmlp 5 hours ago

It is the Java Virtual Machine for a reason.

Without Google's godfather, Kotlin would be gone for now.

Kotlin is so great, where is the Kotlin Virtual Machine, showing how Kotlin can stand on its own?

jayd16 4 hours ago

Uhm, Kotlin does compile to native without the JVM doesn't it? It runs in the JVM for Java interop, no?

https://kotlinlang.org/docs/native-overview.html

dathanb82 4 hours ago

pjmlp 4 hours ago

Sharlin 4 hours ago

To be fair, sealed classes were introduced in Java 15 back in 2020. But granted pattern matching is what makes them really useful.

pixelstack 4 hours ago

Scala*

troupo 5 hours ago

Of all languages the only one it's trying to catch up to (and in places outran) is C#

With many others it doesn't compete because it would need a from-scratch rewrite of the runtime (Erlang/Elixir), or a from-scratch redesign of the type system (Rust, perhaps Swift).