alt.hn

12/7/2025 at 3:08:17 PM

Scala 3 slowed us down?

https://kmaliszewski9.github.io/scala/2025/12/07/scala3-slowdown.html

by kmaliszewski

12/7/2025 at 4:38:46 PM

I am not a scala fan and do not care for it, but I upvote for the thorough thought process, breakdown, and debugging of the problem. This is how technical blogs should be written. AI aint got shit on this.

by game_the0ry

12/7/2025 at 9:12:18 PM

> I was refreshing one of our services. Part of this process was to migrate codebase from Scala 2.13 to Scala 3.

My first question was: why?

by sema4hacker

12/7/2025 at 10:54:49 PM

Scala 3 is sorta a new language, bringing a lot of improvements to the type system: https://docs.scala-lang.org/scala3/new-in-scala3.html

It also looks like it has some improvements for dealing with `null` from Java code. (When I last used it I rarely had to deal with null (mostly dealt with Nil, None, Nothing, and Unit) but I guess NPEs are still possible and the new system can help catch them.)

by pxc

12/8/2025 at 5:00:12 AM

If you're going to "refresh" a codebase you probably want it to be on the current version of things. Old dependencies rot, like it or not. I don't think there's any timeframe for Scala 2 EOL yet, but new development is happening in 3.

by lmm

12/8/2025 at 4:11:42 AM

Why not though the upgrade process from 2.13 to 3 is pretty smooth. And you get all the new language features. I can think of a few that I actually like. I’ll just mention enums because it’s a good example.

by dionian

12/7/2025 at 4:59:54 PM

In Scala 3, the inline keyword is part of the macro system.

When inline is used on a parameter, it instructs the compiler to inline the expression at the call site. If the expression is substantial, this creates considerable work for the JIT compiler.

Requesting inlining at the compiler level (as opposed to letting the JIT handle it) is risky unless you can guarantee that a later compiler phase will simplify the inlined code.

There's an important behavioral difference between Scala 2 and 3: in 2, @inline was merely a suggestion to the compiler, whereas in 3, the compiler unconditionally applies the inline keyword. Consequently, directly replacing @inline with inline when migrating from 2 to 3 is a mistake.

by _old_dude_

12/8/2025 at 2:59:20 AM

> There's an important behavioral difference between Scala 2 and 3: in 2, @inline was merely a suggestion to the compiler, whereas in 3, the compiler unconditionally applies the inline keyword. Consequently, directly replacing @inline with inline when migrating from 2 to 3 is a mistake.

This reminds me of a similar lesson C/C++ compilers had to learn with the "register" keyword. Early versions treated the keyword as a mandate. As compiler optimizers became more refined, "register" was first a recommendation and then ultimately ignored.

The C++ inline keyword is treated similarly as well, with different metrics used of course.

EDIT:

Corrected reference to early C/C++ keyword from "auto" to "register".

by AdieuToLogic

12/8/2025 at 4:19:04 PM

> The C++ inline keyword is treated similarly as well, with different metrics used of course.

You are thinking of C's inline/static inline.

C++'s "inline" semantics (which are implied for constexpr functions, in-class-defined methods, and static constexpr class attributes) allow for multiple "weak" copies of a function or variable to exist with external linkage. Rather than just an optimization hint it's much more of a "I don't want to put this in any specific TU" these days.

by TuxSH

12/8/2025 at 3:08:14 AM

Do you mean the ‘register’ keyword?

by cpeterso

12/8/2025 at 3:47:47 AM

My root-cause analysis:

I was visualizing Scala method definitions and associated the language's type inference with keyword use, thus bringing C++'s "auto" keyword to mind when the long-since deprecated "register" keyword was the correct subject.

It would appear LLM's are not the only entities which can "hallucinate" a response. :-D

by AdieuToLogic

12/8/2025 at 3:20:26 AM

> Do you mean the ‘register’ keyword?

Yes I did, my bad.

by AdieuToLogic

12/8/2025 at 11:39:57 AM

And now we have things like `__attribute__((always_inline))` for GCC where you are completely, 100% sure that you want to inline :).

by kokada

12/7/2025 at 6:04:03 PM

Kotlin heavily uses the inline keyword basically everywhere, to get rid of lamdba overhead for functions like map. Basically every stdlib and 3rd part library function that takes a lamdba is inlined.

In general it's a performance benefit and I never heard of performance problems like this. I wonder if combined with Scala's infamous macro system and libraries like quicklens it can generate huge expressions which create this problem.

by dtech

12/7/2025 at 8:20:06 PM

This is one example why being a guest language isn't optimal.

They should have made use of JVM bytecodes that allow to optimize lambdas away and make JIT aware of them, via invokedynamic and MethodHandle optimizations.

Naturally they cannot rely on them being there, because Kotlin also needs to target ART, JS runtimes, WebAssembly and its own native version.

by pjmlp

12/7/2025 at 8:28:25 PM

Kotlin existed before Java 7 and kept support JVM 1.6 for a long time (mainly because of Android)

Even then, they benchmarked it, and inlining was still faster* than invokedynamic and friends, so they aren't changing it now JVM 1.8+ is a requirement.

* at the expense of expanded bytecode size

by dtech

12/7/2025 at 8:41:20 PM

Java 7 to Java 25 is a world apart, and then on which JVM?

Naturally it is a requirement, JetBrains and Google only care about the JVM as means to launch their Kotlin platform, pity that they aren't into making a KVM to show Kotlin greatness.

If it feels salty, I would have appreciated if Android team was honest about Java vs Kotlin, but they weren't and still aren't.

If they were, both languages would be supported and compete on merit, instead of sniffling one to push their own horse.

Even on their Podcast they reveal complete lack of knowledge where Java stands.

by pjmlp

12/7/2025 at 9:37:39 PM

Maybe the JVM team should listen to the market then and disable the jigsaw encapsulation that keeps devs on 1.8. Forcing a questionable security framework on everyone is why 1.8 is still used. Again, this is a problem because the PMs (and some devs) refuse to listen to what the market wants. So they are stuck keeping a 20 year old version of the code working. Serves them right to have to do this. It is their penance for being too arrogant to listen to the market.

PS Yes, I know, there is some weird way to disable it. Somehow that way changes every version and is about as non-intuitive as possible. And trying to actually support the encapsulation is by a wide margin more work than it is worth.

by hunterpayne

12/8/2025 at 11:22:24 AM

First, the number of projects still on 8 is low, and almost all of them are legacy projects with little to no evolution.

Second, modules' encapsulation is not what caused the migration difficulties from 8 to 9+, evidenced by the fact that it wasn't even turned on until JDK 16: https://openjdk.org/jeps/396. From JDK 9 through 15, all access remained the same as it was in 8. The reason a lot of stuff broke was the JDK 9 was the largest release ever, and it began changing internals after some years of stagnation. Many JDK 8 libraries had used those internals and had become dependent on them not changing - though there was no promise of backward compatibility - because there was no encapsulation.

Finally, the market clearly wants things like projects Loom and Panama and Valhalla, things that wouldn't have been possible without encapsulation (at least not without breaking programs that depend on internals over and over). It's like people complaining about the noise and dust that installing cable ducts causes and say, "nobody asked for this, we just asked for fast internet!"

by pron

12/7/2025 at 11:35:39 PM

I'm pretty sure that the majority of shops that aren't worrying about Android have moved on from Java 8. The JVM team only keep Java 8 working for customers paying them lots of money for extended support contracts. And that's only because they have this long-term extended support system for all LTS JVM releases (they are also still supporting 11 in a similar manner).

On the other hand, Android doesn't even support Java 8. It supports the long-dead Java 7 plus a subset of Java 8 features. Android essentially froze their core application runtime in amber over ten years ago and have just been adding layer upon layer of compiler-level sugar ever since. The effect is an increasing loss of the benefit of being on the Java platform, in terms of code sharing.

by clhodapp

12/8/2025 at 5:01:42 AM

Didn't Google win the lawsuit with Oracle?

I never understood why they do not track the OpenJDK versions. I don't work on Android apps.. but it seems mildly insane to basically have a weird almost-Java where you aren't even sure if you can use a given Java lib.

Ex: I just took a look at a dependency I'm using

https://github.com/locationtech/spatial4j

Can it be used on Android..? I have no idea

From what I understand it's a weird stack now where nobody is actually writing Java for Android.

I'm still waiting for the day I can write a Clojure app for my phone..

(and not a Dart chat app.. but something actually performant that uses the hardware to the full extent)

by geokon

12/8/2025 at 6:02:25 AM

> I never understood why they do not track the OpenJDK versions. I don't work on Android apps.. but it seems mildly insane to basically have a weird almost-Java where you aren't even sure if you can use a given Java lib.

NIH syndrome

> (and not a Dart chat app.. but something actually performant that uses the hardware to the full extent)

I used to work on Android, quit two years ago and have used Flutter since, it's a breath of fresh air. It does use the hardware to the full extent, imo it's significantly more performant: it does an end-around all the ossified Android nonsense.

by refulgentis

12/8/2025 at 6:22:48 AM

Hmm, so if you wanted to make an AR app, or some audio processing app, would you do that in Flutter? All the projects I have in mind involve using the camera/microphone/gps etc. Looking at Dart sample projects it just seemed to be quite different from what they're aiming at

by geokon

12/8/2025 at 6:00:36 PM

My caffeinated instinct is to say basically "yes I'd do anything in Flutter", I honestly would rather stop coding than go back to anything I've done before (ObjC/Swift/Java/Kotlin with side journeys in C++). It boggles my mind how much of a different job dev is with true hot reload.

More carefully, and dealing with what you're indicating more directly:

There's stuff that we just need every millisecond of performance from.

Generally, Dart's great, I don't notice any difference between iOS / Android standard UI platforms.

But...for example, Flutter's image decoding is actually using "native" code behind the scenes, i.e. calling into C or OS-level APIs or browser APIs as needed on each platform. And there's a Flutter package called "image" that's Dart-native but I abhor because I know it's going to be higher latency than going thru lower-level code. (now I'm wondering how Java does this...I wonder if its JNI...)

Let's do a scenario: I've been contracted to build a bus route app for the local gov't. They want an AR feature. What happens if I choose to build on Flutter, build out the basic features, then get to the AR, and I'm getting 5 fps?"

Solution to that is "plugins" - https://docs.flutter.dev/packages-and-plugins/developing-pac... - the intro to the doc is way out of date, like years. TL;DR is you can drop in C / Swift / Java / whatever easily as needed.

You can get a sense of what that looks like from my package for doing ML inference here: https://github.com/Telosnex/fonnx, specifically https://github.com/Telosnex/fonnx/tree/main/lib/models/minis...: X_native.dart shows us calling into shared C code on every non-mobile platform. On mobile, I have to take a dep on specific packaged & code signed libraries provided by Microsoft for ONNX. Then, I (AI, at this point) writes Swift and Kotlin to call into that library. (Swift: https://github.com/Telosnex/fonnx/blob/main/ios/Classes/OrtM..., Kotlin: https://github.com/Telosnex/fonnx/blob/main/android/src/main...)

This might feel convoluted at first, it did to me, but really, all that's going on is: when things are slow, we write a Dart interface, then for each platform where we want to use native code, provide impls of that interface in native.

by refulgentis

12/8/2025 at 10:30:30 AM

RE: Flutter

Yeah, I'm currently developing a Flutter app and also using flutter_rust_bridge to separate the business logic and I can hardly believe how enjoyable it is.

Other than the initial project setup which is a me and Nix flakes problem it all comes together pretty smoothly.

by aquariusDue

12/7/2025 at 10:16:56 PM

I have not done a Java 8 project in years, other than Android because the reasons we all know.

Maybe Google could finally support latest Java versions on Android, instead of begrudgingly update when Kotlin lags behind Maven Central most used versions.

Which by the way is a Java 17 subset, not Java 8, when supporting Android versions below Android 12 isn't required.

by pjmlp

12/7/2025 at 10:07:46 PM

What you're asking for is essentially commercial support from Oracle.

by imtringued

12/7/2025 at 10:59:59 PM

Nope, what I am asking for is disabling an on by default feature that maybe 1% of the market wants and/or needs and creates significant pain for the other 99%. By the time strong encapsulation meets an attacker, the battle is already lost most of the time.

by hunterpayne

12/8/2025 at 2:30:47 AM

That feature is necessary to enable future enhancements. It’s an important stepping stone. Just update your code. I’m doing it on 20 year old legacy billion dollar code base. It can be done.

by Pet_Ant

12/8/2025 at 6:06:21 AM

It's not just for security, it's also for maintainability. Frankly being able to reflect across package boundaries has always seemed like a misfeature for maintainability to me. The code you have that is broken by Java 9 was already badly behaved, the JVM was just lenient about it.

by jolux

12/7/2025 at 9:10:01 PM

There are Kotlin compiler flags to default to "indy" optimization, and which may be enabled by default for some time now?

Also not all Kotlin inlines are lambdas or even include method calls

by gavinray

12/7/2025 at 7:54:54 PM

The killer is specifically the inlining of macros -- which Kotlin lacks.

And not all macros, but just the ones which expand to massive expressions

Think template expressions in C++ or proc macros in Rust

by gavinray

12/7/2025 at 4:49:32 PM

> After upgrading the library, performance and CPU characteristics on Scala 3 became indistinguishable from Scala 2.13.

We had a similar experience moving Ruby 2->3, which has a ton of performance improvements. It was in fact faster in many ways but we had issues with RAM spiking in production where it didn't in the past. It turned out simply upgrading a couple old dependencies (gems) to latest versions fixed most of the issues as people spotted similar issues as OP.

It's never good enough just to get it running with old code/dependencies, always lots of small things that can turn into bigger issues. You'll always be upgrading the system, not just the language.

by dmix

12/7/2025 at 6:17:55 PM

> After upgrading the library, performance and CPU characteristics on Scala 3 became indistinguishable from Scala 2.13.

Checking the bug mentioned, it was fixed in 2022.

So, I’m wondering how one would upgrade to scala 3, while keeping old version of libraries?

Keeping updated libraries is a good practice (even mandatory if you get audits like PCI-DSS).

That part puzzled me more than the rest.

by jiehong

12/7/2025 at 9:49:13 PM

> Keeping updated libraries is a good practice

First, the "good practice" argument is just an attempt to shut down the discussion. God wanted it so.

Second, I rather keep my dependencies outdated. New features, new bugs. Why update, unless there's a specific reason to do so? By upgrading, you're opening yourself up to:

- Accidental new bugs that didn't have the time to be spotted yet.

- Subtly different runtime characteristics (see the original post).

- Maintainer going rogue or the dependency getting hijacked and introducing security issues, unless you audit the full code whenever upgrading (which you don't).

by tasuki

12/9/2025 at 3:46:23 PM

It's true that you can satisfy the audit just by running dependency scans and updating the ones that come back vulnerable. Unfortunately, in a lot of ecosystems, that ends up looking the same as keeping all your libraries updated.

You can instead document exceptions for why all those vulnerabilities doesn't apply to your app, but that's sometimes more trouble.

by Cpoll

12/7/2025 at 7:22:49 PM

I'm confused as well, because he wrote

> I did it as usual - updating dependencies

but later

> After upgrading the library, performance and CPU characteristics on Scala 3 became indistinguishable from Scala 2.13.

So... he didn't upgrade everything at first? Which IMO makes sense, generally you'd want to upgrade as little as possible with small steps. He just got unlucky.

by mystifyingpoi

12/7/2025 at 7:40:30 PM

It would have been a transitive dependency based on the comments about the library being "transparent" and the author unaware it was even used.

Pinning specific versions of transitive deps is fairly common in large JVM projects due to either security reasons or ABI compatibility or bugs

by gavinray

12/7/2025 at 7:20:20 PM

> Checking the bug mentioned, it was fixed in 2022.

I was considerably less impressed by the reporting when I finally found out the culprit.

Sure it was “Scala 3” … but not really.

It was an interaction of factors and I don’t think it would take away from the story to acknowledge that up front.

by fn-mote

12/8/2025 at 1:05:58 AM

> So, I’m wondering how one would upgrade to scala 3, while keeping old version of libraries?

The normal way.

> Keeping updated libraries is a good practice

So is changing one thing at a time, especially when it's a major change like a language version upgrade.

by lmm

12/7/2025 at 7:44:16 PM

If your Maven/Gradle/SBT build specifies a version constraint for a third party lib, updating your Scala or Kotlin version doesn't affect this

(For scala-specific libs, there is a bit more nuance, because lib versions contain scala version + lib version, e.g. foolib:2.12_1.0.2 where 2.12 = scala version)

by gavinray

12/7/2025 at 9:29:10 PM

The problem with Scala 3 is that nobody asked for it. The problem with Scala 2 is that the type inference part of the compiler is still broken. Nobody worked on that. Instead they changed the language in ways that don't address complaints. Completely ignore the market and deliver a product nobody wants. That's what happened here.

PS Perhaps they should make an actual unit test suite for their compiler. Instead they have a couple of dozen tests and have to guess if their compiler PR will break things.

by hunterpayne

12/7/2025 at 9:55:23 PM

It's sad but I generally agree. Scala was in my view pretty well positioned for an up and coming language ~2010-15. Not only did the scala 3 rewrite fail to address many of the most common pain points -- compile times and tooling immediately come to mind -- the rewrite took many years and completely stalled the momentum of the project. I have to wonder at this point who is actually starting a new project in scala in 2025.

It's really a shame because in many ways I do think it is a better language than anything else that is widely used in industry but it seems the world has moved on.

by thefaux

12/8/2025 at 9:03:05 AM

> It's really a shame because in many ways I do think it is a better language than anything else that is widely used in industry but it seems the world has moved on.

I'm really hoping that https://flix.dev/ will learn from the mistakes of Scala. I t looks like a pretty nice spiritual successor to Scala.

by theLiminator

12/8/2025 at 9:27:13 PM

> It's really a shame because in many ways I do think it is a better language than anything else that is widely used in industry but it seems the world has moved on.

No it didn't. Scala is powering some of the biggest companies on this planet.

https://business4s.org/scala-adoption-tracker/

It does apparently so well that nobody is even talking about it…

So it seems even better than all the languages people are "talking" (complaining) about.

by still_grokking

12/7/2025 at 11:22:40 PM

>It's sad but I generally agree. Scala was in my view pretty well positioned for an up and coming language ~2010-15

I used Scala for a bit around that period. My main recollection of it is getting Java compiler errors because Scala constructs were being implemented with deeply nested inner classes and the generated symbol names were too long.

by zahlman

12/8/2025 at 9:04:46 PM

> My main recollection of it is getting Java compiler errors because Scala constructs were being implemented with deeply nested inner classes and the generated symbol names were too long.

Sounds like you've used some beta version over 15 years ago.

Nothing like described happens in current Scala and it's like that as long as I can think back. Never even heard of such bugs like stated.

Coming up with such possibly made up stuff over 15 years later sounds like typical FUD, to be honest.

by still_grokking

12/7/2025 at 10:16:43 PM

I tried getting into Scala several times and kept going back to Clojure. Unless you are into type system minigames Clojure has many of the things Scala advertises but without the dumptruck of Scala overhead and complexity. Another commenter briefly touched on this but it's a language made by academics for academics to play with language design. It was a little weird it blew up in industry for a while.

by lispisok

12/7/2025 at 11:30:26 PM

> it's a language made by academics for academics to play with language design. It was a little weird it blew up in industry for a while.

Yep. They have always been pretty honest about this.

I think that it blew up in industry because it really was ahead of its time. Type systems were pretty uncool before Scala. It proved that you could get OO and FP in a single type system.

Actually, a big part of reason for doing Scala 3 was rebasing the language on a more rigorous basis for unifying OO and FP. They felt that for all their other big ideas, it was time to rethink the fundamentals.

by acjohnson55

12/7/2025 at 11:53:36 PM

> Type systems were pretty uncool before Scala

I’m not up on programming language engineering as much as I should be at 37, could you elaborate a bit here? (To my untrained ear, it sounds like you’re saying Scala was one of the first languages that helped types break through? And I’m thinking that means, like, have int x = 42; or Foo y = new Foo()”

by refulgentis

12/8/2025 at 12:56:16 AM

Not types, type-safety. Things like covariant and contravariant type declarations, implicit types (variables looked up by type instead of by label), and other things that you need to make a type safe system/service/application. The problem is that that feature of a language is massively oversold. Its nice but to pretend it prevents bugs or is even a great design goal is questionable and not backed up by research (as they claim).

by hunterpayne

12/8/2025 at 4:15:04 AM

But it’s still a way more powerful and expressive type system than Java. So using it in a JVM ecosystem is a perfect fit.

by dionian

12/8/2025 at 9:33:33 PM

> Its nice but to pretend it prevents bugs or is even a great design goal is questionable and not backed up by research (as they claim).

That's why people use JavaScript instead of Rust for critical systems, right?

Claiming in the year 2025 that strong static types don't provide massive advantages is almost laughable, TBH. This was settled long ago, and the whole industry now understands that type safety is inevitable to create reliable and scalable systems.

by still_grokking

12/8/2025 at 9:28:22 PM

> It was a little weird it blew up in industry for a while.

It never went away. It only got more:

https://business4s.org/scala-adoption-tracker/

by still_grokking

12/9/2025 at 7:43:32 AM

Wow, 34 companies with "possibly" 233 more!

I don't see the chart with changes of number of companies using Scala over time. But even without the chart - if after 15 years there are less than 300 companies in total, that's a bit depressing.

Of course legacy never goes away, and even 20 years down the line there will still be some demand for Scala programmers. Similar to how Cobol still lives on. But in my experience the language isn't growing anymore, even slowly dwindling in userbase. And this became way worse after Scala 3 mess.

by Rogach

12/9/2025 at 10:26:53 PM

The website is a private undertaking which started literally a few days ago. It's not some official complete tracker.

The point was to show that big corps are dependent on Scala, often at their core.

Scala is likely not for everybody, but where you need to write safe high level code there is more or less no alternative, not even on the horizon. Scala is simply very likely where Rust will end up after the honeymoon, when people realize that feature rich, safety first languages aren't for the mass market, where mostly only the cost of initial development counts.

by still_grokking

12/10/2025 at 5:20:05 AM

True, Scala (the language) offers lots of great functionality. And Scala 3 brought some important improvements.

But safety is not the only important aspect of a programming language. For me personally the community (libraries, tools, forums, blogs, etc) became much more important over the years, and I feel that Scala 3 really hurt the community angle.

by Rogach

12/15/2025 at 1:27:00 AM

> But safety is not the only important aspect of a programming language.

That's also part of what I've said.

The point still being: Where you need a safe language there is no way around it, and Scala is still one of the very few options you have at all. Scala is in that regard indispensable.

> I feel that Scala 3 really hurt the community angle

I don't see that.

Everything relevant, besides Spark, is now on Scala 3, and this is already like that since a few years.

But I agree that Scala documentation / references / tutorials are to this very day lacking. This was and still is a real issue, and that's actually a very relevant one. I really hope this gets better with time.

The sub-optimal situation regarding docs does though not prevent people from starting new projects in Scala.

In fact Scala 3 is again ahead of the pack. It provides features not seen so far in any real world language and will almost certainly again pioneer the implementation of new language concepts in the large, as it did already in the past with its pragmatic approach to a OOP / FP fusion.

Just see for yourself what is currently happening:

https://softwaremill.com/understanding-capture-checking-in-s...

by still_grokking

12/8/2025 at 4:14:07 AM

The simplicity of closure is certainly a main part of its appeal. I’ve never done OOP in it, but I don’t think I want to. I have a lot of respect for it though.

by dionian

12/8/2025 at 3:41:45 AM

It was absolutely amazing how stubborn and ridiculous the whole bracket-less syntax change was handled. It was basically a dictatorial decision that they pretended to be a community decision. It was just pushed and tons of people voiced their disapproval. In the end it was "so bad so sad you can always reenable brackets".

They did it to try to appeal to Pythonists.. turns out that wasn't why Pythonists didn't use scala in the first place.

by monksy

12/8/2025 at 4:13:10 AM

I think it’s nice to be able to use it. But like pretty much everything in scala, it’s a huge smorgasbord of things from which you can choose. I personally don’t use that syntax, but it’s cool that I can and sometimes I do just for fun.

by dionian

12/8/2025 at 11:00:16 AM

A language should not be complicated. (Wish Odersky, capable as he is, kept working on his much-verlooked TurboModula).

Simple:

- Scheme

- C

- Pascal

- Go

- Lua

Complicated

- PL/1

- C++ 2024

- Scala 3

Still borderline or beyond?

- Rust

- Java (>850 pp. lang. specification...)

by jll29

12/8/2025 at 9:47:38 PM

Extremely weird list.

The Scala spec is much shorter than the C spec… Also it's of course much shorter than Rust, where nobody has a real issue with its complexity, at least nobody is complaining really loudly.

The C and Go specs are actually extremely involved, long, and complex given that the languages almost don't have any features at all.

But comparing language specs isn't a 100% fair metric.

One should instead look at formal language semantic definitions written all in the same way.

If you look at these you will for example learn that the C semantics are much more complex than for example Java.

Check out https://kframework.org/ to learn more. (A list of semantics for different languages can be found on the "projects" sub page).

by still_grokking

12/8/2025 at 9:37:48 PM

> In the end it was "so bad so sad you can always reenable brackets".

This is not true.

Nobody ever proposed to replace the old syntax!

The new syntax was, and is, optional, and that's exactly like designed from the very beginning.

by still_grokking

12/9/2025 at 7:58:16 AM

They didn't explicitly propose replacing the syntax, true. But to an outsider, it sure looked like the new syntax was a priority - all the examples and code snippets in the official docs defaulted to the new syntax, making them infuriating to read for someone accustomed to braces.

If I recall correctly, later they added a switch allowing one to choose between syntax versions in the online docs. But it wasn't done right from the start, and when that was finally added most of the damage was done, people already lost interest.

I understand that removing braces might feel harmless - but it really makes the code harder to read for people that use braces all the time.

If someone's brain is accustomed to seeing braces everywhere, reading code with them becomes almost automatic, handled by "low-level" parts of the brain. If the syntax is changed, then "low-level" brain areas have to pass work to "higher-level" areas, which increases energy requirements and processing latency. So reading unfamiliar syntax is literally harder.

Incidentally, that's also why many people are so picky about grammar - grammatical errors make the text noticeably harder to read.

Source: have a degree in neurophysiology.

by Rogach

12/9/2025 at 10:18:14 PM

Examples and code snippets in the official docs of course default to the new syntax, making them well readable for all people accustomed to Scala's new syntax.

> If I recall correctly, later they added a switch allowing one to choose between syntax versions in the online docs.

Stating this, which is not, and never was true creates the impression you're talking about things you have no clue about.

The point is: Removing braces really makes code much easier to read for people who get distracted by useless line noise!

> So reading unfamiliar syntax is literally harder. > […] > Source: have a degree in neurophysiology.

You need a degree to understand something such obvious? Never mind…

The point is: New syntax is only new in the first few hours of contact with it.

Anybody who uses more than one language knows that switching languages is in fact a bit distracting, but at latest on the second day you completely stop thinking about syntax, and than switching back to whatever was before is as hard as the previous switch to the current thing. Usually this happens already after a few hours for languages you already know.

As we're talking about neurophysiology: As a matter of fact filtering "noise" — irrelevant information — from sensory input is a hard task for the brain. So having less distracting useless noise in the input helps to concentrate on the stuff that actually matters!

Braces in code are 100% redundant, useless noise. The only reason they were added in the first place was to make code simpler to parse for computers, something that does not matter any more since many decades. So there is no rational reason any more to pollute code with useless, distracting noise.

by still_grokking

12/10/2025 at 5:21:36 AM

I feel that I need to preface my answer with the defusing disclaimer: I understand that you love the language very much. And statements like the ones I make may hurt, because they say bad stuff about the thing you love. But getting defensive might detract from otherwise interesting discussion.

In fact, I also love Scala. I've dedicated lots of my time to working with it (almost 15 years at this point!), I've been with it since 2.8.x days. And I really lament that it fell out of favor and huge swaths of the community left.

> Stating this, which is not, and never was true creates the impression you're talking about things you have no clue about.

Of course it is possible that I have misremembered, so I went and checked. It was a mistake on my part to make such a statement and not to provide an actual link.

Not only it was that way, it actually still is. See the official Scala 3 reference: https://docs.scala-lang.org/scala3/reference/

All the code examples there use the new syntax. And I would guess that "Scala 3 reference" is the document that Scala 2 veterans (like myself) would have been using when learning about new features and contemplating migration to the new version.

> You need a degree to understand something such obvious? Never mind…

It might be obvious, but I felt that it wasn't obvious to some people (including the ones that were in charge of the documentation for Scala 3), so I wanted to expand a bit on that.

> The point is: New syntax is only new in the first few hours of contact with it.

Of course, but these "first few hours" are exactly the hours that were spent reading the documentation for the Scala 3, and I feel that making those hours harder wasn't the smart choice.

I think that Scala development team made a decision to chase growth, focusing on attracting new users and disregarding the old ones. Looks like they lost that bet - new users didn't come, and many old users were disappointed and left.

New syntax isn't the only problem of Scala 3, and probably it isn't even the biggest one. But it was the most glaring and visible issue - for me, almost every code example in the reference really felt like a spit in the face. Exactly this kind of off-hand dismissal of old-time users was one of the reasons some of the users started moving away from Scala (myself included).

> Braces in code are 100% redundant, useless noise.

The debate about "braces vs significant whitespace" is raging literally for decades. Like many similar debates, it seems that there's no "true solution" and no "true winner" - both sides have heaps of valid arguments.

I assume that both sides have their merits, and it's always a tradeoff between pros and cons of each approach. I use languages that have braces, and I use languages that use indentation - I see pros and cons of each approach. Outright dismissing the other side of the debate by saying that it's "100% useless" seems to be missing lots of nuance.

by Rogach

12/8/2025 at 3:10:55 AM

You capture the root issue quite well.

Now every tool has to adapt to Scala 3. And you guess it? It will take time. Even IntelliJ still doesn't correctly highlight syntax on some parts that also exist in Scala 2. And this has been years after Scala 3 was launched. It's mind-boggling.

They could have improved upon Scala 2 and incrementally add more capabilities. It's obvious they don't care about Scala's industry success. They care mostly about the academic success. Nothing wrong with that, but that should be made very clear.

In Scala, they have a huge debate with zealots arguing against, for example, early return; they would describe how bad it will be blah blah blah e.g. https://tpolecat.github.io/2014/05/09/return.html, meanwhile Kotlin supports early return with absolutely no issue.

by ergocoder

12/7/2025 at 9:56:37 PM

And I wish you read the article, you're comments are completely off topic.

by oelang

12/7/2025 at 10:00:45 PM

Scala has deep roots in the Ivory Towers of Academia, its not shocking they think they know better than their users what the problems with the language are and didn't do any kind of real product management to figure out the actual problems before embarking on a rebuild.

by voidfunc

12/8/2025 at 10:30:35 AM

It wouldn't be a problem, but the issue is a one of expectations.

Was Scala supposed to be a research language (focus on novel features) or an industrial language (focus on stability and maintainability)? I think Oderski wanted the first but many people wished for the second.

by js8

12/8/2025 at 1:04:35 AM

> The problem with Scala 2 is that the type inference part of the compiler is still broken. Nobody worked on that. Instead they changed the language in ways that don't address complaints.

Huh? Type inference is much more consistent and well-specified in 3. In 2 it was ad-hoc so and impossible to fix anything for one codebase without breaking another. There are plenty of legitimate complaints to be had about Scala 3, but this is absolutely not one of them.

by lmm

12/8/2025 at 9:15:05 AM

I was so stoked, when it was released. Loved the approach they take. So, I can say, there was at least one person who asked for it.

With the hindsight, it is not a great mainstream language and the new opinionated language is too hard for junior Joe developers.

Anyway, you clearly have not read the article, as it is about bug in a transitive dependency, not an actual Scala 3 issue.

p.s.: Scala compiler is one of the most aggressively tested pieces of software in the JVM ecosystem.

by vletal

12/8/2025 at 9:18:52 PM

> PS Perhaps they should make an actual unit test suite for their compiler. Instead they have a couple of dozen tests and have to guess if their compiler PR will break things.

You did not even try to formulate it in a way that could be interpreted as you just not knowing; instead you make blatant false statements in the most confident way possible.

Your statement is therefore an outright lie, spreading FUD.

As a matter of fact the Scala compiler has thousands, likely even tens of thousands of test cases.

https://github.com/scala/scala3/tree/main/tests

But that's not all. Scala (2 & 3) has also a test case called "community build" where new compiler releases are tested by compiling millions of LOCs from all kinds of Scala OpenSource projects.

https://github.com/VirtusLab/community-build3

https://github.com/scala/community-build

by still_grokking

12/7/2025 at 9:13:33 PM

The bug reports linked on softwaremill and scala GitHub's are precise and surprisingly small fixes! It does show Scala's power in expressiveness.

Scala is a great language and I really prefer its typesafe and easy way to write powerful programs: https://www.lihaoyi.com/post/comlihaoyiScalaExecutablePseudo... Its a great Python replacement, especially if your project is not tied to ML libraries where Python is defacto, like JS on web.

by xolve

12/7/2025 at 4:56:50 PM

I was involved in a Scala point version migration (2.x) migration a few years ago. I remember it being painful. Although I recall most of the pain was around having lots of dependencies and waiting for libraries to become available.

At the time Scala was on upswing because it had Spark as its killer app. It would have been a good time for the Scala maintainers to switch modes - from using Scala as a testbed for interesting programming-language theories and extensions to providing a usable platform as a general commercially usable programming language.

It missed the boat I feel. The window has passed (Spark moved to Python and Kotlin took over as the "modern" JVM language) and Scala is back to being an academic curiosity. But maybe the language curators never saw expanding mainstream usage as a goal.

by derriz

12/7/2025 at 5:07:39 PM

Outside of Android work, has Kotlin really taken over? My understanding is that Java added a lot of functional programming and that took a lot of wind out of Scala's sails (though Scala's poor tooling certainly never helped anything).

by hylaride

12/7/2025 at 7:32:06 PM

> My understanding is that Java added a lot of functional programming

This is true, but needs more context. Java 8 added Stream API, which (at this time) was a fantastic breath of fresh air. However, the whole thing felt overengineered at many points, aka - it made complex things possible (collector chaining is admittedly cool, parallel streams are useful for quick-and-dirty data processing), but simple everyday things cumbersome. I cannot emphasize how tiring it was to have to write this useless bolierplate

  customers.stream().map(c -> c.getName()).collect(Collectors.joining(", "))
for 1000th time, knowing that

  customers.map(c -> c.getName()).join(", ")
is what users need 99.99999% of the time.

by mystifyingpoi

12/8/2025 at 10:44:29 PM

It's such a blessing to be able to write in Scala

  customers.map(_.name).mkString(", ")
instead of the Java bloat

  customers.stream().map(c -> c.getName()).collect(Collectors.joining(", "))

by still_grokking

12/8/2025 at 9:59:53 AM

It bothers me that majority of languages ignores a nice python approach. `', '.join(any_str_iterable)`. Instead of supporting join for myriads of containers there is a single str method.

by bvrmn

12/8/2025 at 10:39:29 PM

Python's approach is one of the most confusing ways to possibly do it. Not having proper, discoverable methods is super annoying, and I need to look it up every time anew I use Python because it's so unintuitive.

Of course you can write a generic version of `mkString` (as this method is called in Scala), so it's also just one method no matter the container count.

The Python weirdness is actually a direct result from the language lacking generics…

by still_grokking

12/10/2025 at 8:53:27 AM

From typing perspective there is no sense to have Container[T].join() -> str for any T.

by bvrmn

12/15/2025 at 12:24:28 AM

That's obviously the wrong signature.

The semantically correct one is "Container[T : Printable].join(): String"; T must implement the Printable concept, but Python lacks concepts (or type-classes as these are alternatively called).

But this all is irrelevant as this is anyway not the signature of `str.join()` in Python. It's `str.join(Iterable[str]) -> str` there. With sane design and syntax it would just become `Iterable[str].join(str)`.

by still_grokking

12/10/2025 at 1:42:00 PM

I agree, but from convenience perspective there is a lot of sense. Java Streams is actually a good example of a "correct" design, but not very convenient.

by mystifyingpoi

12/11/2025 at 11:34:58 AM

That's my point. Python has convenient and good type design with str.join ignored by other languages.

For example I'm lost which abstract class to inherit in Scala to obtain mkString for my custom container.

by bvrmn

12/15/2025 at 12:41:33 AM

> Python has convenient and good type design with str.join ignored by other languages.

Of course such non-discoverable and unintuitive design gets ignored everywhere!

We just established that even in Python the correct way to do it would be

  Iterable[str].join(str) -> str
but for that Python would need generic iterators on the language level…

> For example I'm lost which abstract class to inherit in Scala to obtain mkString for my custom container.

So you're saying you've been able to implement custom Scala collection types, which is regarded some of the more difficult stuff one could possibly do, but you don't know how to implement an Iterator for your custom collection—as this is all needed for mkString to work? BTW, how did you implement the collection type at all without implementing Iterator for it? Your collection is not Iterable?

TBH, this does not sound very realistic. This sounds more like typical HN Scala FUD. People throwing around some vague, most of the time outright made up issues they've heard about somewhere about 10 - 15 years ago.

by still_grokking

12/7/2025 at 6:17:03 PM

Sort of true, but I often hear this take from Java programmers and it feels like "Blub" [1]/Stockholm syndrome to me.

Personally, I'm extremely glad to not have had to write .toStream().map(...).collect(Collectors.list()) or whatever in years for what could be a map. Similar with async code and exception handling.

For me one of the main advantages of Kotlin is that is decreases verbosity so much that the interesting business logic is actually much easier to follow. Even if you disregard all the things it has Java doesn't the syntax is just so much better.

[1] https://paulgraham.com/avg.html

by dtech

12/8/2025 at 12:14:12 AM

Java 16+

    stream.map(...).toList()
https://bugs.openjdk.org/browse/JDK-8180352

by wrathofmonads

12/8/2025 at 5:02:01 AM

So only 2 bullshit boilerplate calls instead of 3? I guess that's progress.

by lmm

12/7/2025 at 5:29:20 PM

At least where I work, writing new Java code is discouraged and you should instead use Kotlin for backend services. Spring Boot which is the framework we use, supports Kotlin just fine, at the same level as Java. And if you use Jetbrains tools, Kotlin tooling is also pretty good (outside Jetbrains I will admit it is worse than Java). Now, even in new Java projects you can still be using Kotlin because it is the default language for Gradle (previously it was Groovy).

by aarroyoc

12/7/2025 at 8:04:11 PM

My org had to write a pivotal backend service on the JVM, due to JDBC having the largest number of data source adapters.

The choice was Kotlin. Scala is too "powerful" and can be written in a style that is difficult for others, and Java too verbose.

Kotlin is instantly familiar to modern TypeScript/Swift/Rust etc devs.

The only negative in my mind has been IntelliJ being the only decent IDE, but even this has changed recently with Jetbrains releasing `kotlin-lsp` for VS Code

https://github.com/Kotlin/kotlin-lsp

by gavinray

12/8/2025 at 1:12:39 AM

Java did indeed add more FP to the language, but Java's type system is still fairly primitive compared to Scala's.

by kelnos

12/7/2025 at 5:25:07 PM

Java's new features are always going to be on paper. The ecosystem, with all its legacy code, is always going to be a decade behind. And if you are starting a new project, why would you pick Java over Kotlin?

by esafak

12/7/2025 at 6:44:16 PM

> And if you are starting a new project, why would you pick Java over Kotlin?

Because in 5-10 years you'll have a Java project that people can still maintain as if it's any other Java project. If you pick Kotlin, that might at that point no longer be a popular language in whatever niche you are in. What used to be the cool Kotlin project is now seen as a burden. See: Groovy, Clojure, Scala. Of course, I recognize that not all projects work on these kinds of timelines, but many do, including most things that I work on.

by frje1400

12/7/2025 at 9:47:01 PM

Clojure has never been a popular language, nor has it aimed to be mainstream. That is the Lisp curse. It has never positioned itself as a "better Java". It shines in applications where immutable, consistent, and queryable data is crucial, and it has found another niche in UIs through ClojureScript.

by wrathofmonads

12/8/2025 at 6:12:23 AM

I don't think Clojure belongs there. It was never as big as Kotlin, but it's got great community, longevity and takes backwards compatibility very seriously, and 10 year old Clojure projects seem to be aging at least as well as 10 year old Java projects.

by fulafel

12/7/2025 at 8:23:59 PM

Because the Java Virtual Machine is designed for Java, and that is what all vendors care about.

Kotlin is Google's C#, with Android being Google's .NET, after Google being sued by coming up with Google's J++, Android Java dialect.

Since Google wasn't able to come up with a replacement themselves, Fuchsia/Dart lost the internal politics, they adopted the language of the JetBrains, thanks to internal JetBrains advocates.

by pjmlp

12/8/2025 at 12:11:20 AM

| Android being Google's .NET, after Google being sued by coming up with Google's J++, Android Java dialect.

The Oracle v Google was specifically over copyright infringement concerning the Java APIs used in Android's original implementation (Dalvik/ART), not about creating a "J++" dialect.

Android never ran a JVM on mobile because it cannot be optimized for resource constrained devices a solution like DalvikVM was necessary. If you want to level critiques about creating fragmented dialects of Java I would recommend starting with J2ME. The only nice thing I can say about J2ME is at least it died.

The Android ecosystem was far too mature for Fuchsia/Dart to be successful without a very compelling interop story that was never produced.

As a technology Kotlin met Android's platform and community needs. Advocacy and politicking played a minimal, if any, role.

by bhawks

12/8/2025 at 6:18:50 AM

Lies sold by Google.

Nokia and Sony Ericsson were using J2ME perfectly fine, as did Blackberry. I should know ad ex-Nokian.

Kotlin met nothing, it was pushed by Kotlin heads working on Android Studio, telling lies comparing Kotlin to Java 7, instead of Java was already offering at the time.

To this day they never do Kotlin vs Java samples, where modern Java is used, rather the version that bests fits their purpose to sell why Kotlin.

Fragmentation, what a joke, the fragmentation got so bad in Android, that JetPack libraries, previously Android X, exist to work around the fragmentation and lack of OEM updates.

Gosling said it better, regarding Google's "good" intentions

https://www.youtube.com/watch?v=ZYw3X4RZv6Y&feature=youtu.be...

by pjmlp

12/8/2025 at 3:42:47 PM

J2ME was an alphabet soup of incompatible implementations stuck somewhere between Java 1.2 and 1.3. Getting code to run across device manufacturers was a huge engineering burden. In fact doing something like JetPack for that world would be technically impossible.

If Sun was offering some technically relevant foundation for the smartphone era, it would have been able to actually have some adoption. They were starting from a leading position (obviously - see blackberry or Nokia), and in the space of 3 to 4 years they completely disappeared.

by bhawks

12/8/2025 at 5:19:40 PM

> J2ME was an alphabet soup of incompatible implementations

So Google?

(alphabet)

by re-thc

12/8/2025 at 3:41:15 PM

> And if you are starting a new project, why would you pick Java over Kotlin?

I've written multiple production services in Kotlin Spring Boot. Now, we're building a new system and using Java 21 (25 soon).

Why? Kotlin the language is great, but there are corresponding tradeoffs in interop. Meanwhile, Java the language has improved to the point that it's good enough, and Java feels like it's headed in the right direction. In my opinion, AI models are better at Java than Kotlin. If you prefer a weaker claim, the models are trained on more Java code than Kotlin code.

Finally, from an enterprise perspective, it is a safer long-term investment for a Java shop to own an application written in Java rather than in Kotlin.

by spicybbq

12/7/2025 at 5:33:40 PM

That's kind of what I'm asking. I did have a former co-worker write a micro service in Kotlin around 2018. He said that as nice as the language is, the ecosystem was (at the time, not sure how it is today) so utterly dominated by Android development, that he said he wouldn't recommend using it again - half the time he was calling out Java anyways.

by hylaride

12/7/2025 at 9:13:29 PM

Kotlins "ecosystem" is all of Java, and then all of Kotlin.

Put another way: Java only has access to a subset of the ecosystem

Almost all of the backend libraries I use are Java libs. Some of them have additional Kotlin extension libs that add syntax sugar for more idiomatic code.

by gavinray

12/7/2025 at 5:34:57 PM

I use kotlin and I do not feel oppressed by Android in any way. And I'd rather call Java libraries from Kotlin than Java. Many have Kotlin wrappers.

by esafak

12/7/2025 at 6:12:50 PM

That's a weird take. Even if true, kotlin has perfect interop with calling Java libs so there's not really a downside to keep using Java libs. There's not that much demand for kotlin-specific libs outside multiplatform which includes Android.

For what it's worth, Spring has first tier Kotlin support, I haven't noticed this bias.

by dtech

12/7/2025 at 6:19:39 PM

It’s a lot cheaper to hire for Java than for „modern“ languages.

by adrianN

12/8/2025 at 11:15:20 PM

People on HN down-voting facts?

And yes, "you get what you pay for" is part of this.

by still_grokking

12/7/2025 at 11:31:26 PM

Have you ever heard the expression "you get what you pay for?"

by blandflakes

12/7/2025 at 9:37:25 PM

Kotlin hasn’t made much of an impact in server-side development on the JVM. I’m not sure where this perception comes from, but in my experience, it’s virtually nonexistent in the local job market.

by wrathofmonads

12/7/2025 at 11:15:48 PM

another issue with kotlin, because it encourage Java ecosystem usage like Spring is not much differentiation that could drive adoption.

by strobe

12/7/2025 at 10:06:11 PM

Why is your personal experience relevant to the wider market? How many companies and locations did you survey for that?

by izacus

12/7/2025 at 8:22:36 PM

Kotlin is an Android language, because Google says so, and they stiffle Java support on purpose (Java 17 LTS subset currently).

Outside Android, I don't even care it exists.

If I remember correctly, latest InfoQ survey had it about 10% market share of JVM projects.

by pjmlp

12/7/2025 at 4:15:19 PM

For me the main takeaway of this is that you want to have automated performance tests in place combined with insights into flamegraphs by default. And especially for these kind of major language upgrade changes.

by spockz

12/7/2025 at 9:27:49 PM

Benchmarking requires a bit of different setup than the rest of the testing, especially if you want down to the ms timings.

We have continous benchmarking of one of our tools, it's written in C++, and to get "same" results everytime we launch it on the same machine. This is far from ideal, but otherwise there be either noisy neighbours, pesky host (if it's vm), etc. etc.

One idea that we thought was what if we can run the same test on the same machine several times, and check older/newer code (or ideally through switches), and this could work for some codepaths, but not for really continous checkins.

Just wondering what folks do. I can assume what, but there is always something hidden, not well known.

by malkia

12/7/2025 at 9:39:59 PM

I agree for measuring latency differences you want similar setups. However, by running two versions of the app concurrently on the same machine they both get impacted more or less the same by noisy neighbours. Moreover, by inspecting the flamegraph you can, manually, see these large shifts of time allocation quickly. For automatic comparison you can of course use the raw data.

In addition you can look at total cpu seconds used, memory allocation on kernel level, and specifically for the jvm at the GC metrics and allocation rate. If these numbers change significantly then you know you need to have a look.

We do run this benchmark comparison in most nightly builds and find regressions this way.

by spockz

12/8/2025 at 1:23:04 AM

Good points there - Thanks @spockz!

by malkia

12/8/2025 at 9:16:57 PM

https://en.wikipedia.org/wiki/Hardware_performance_counter can help with noisy neighbors. I am still getting into this.

by esafak

12/9/2025 at 6:56:40 AM

Yes, that can help with detecting how much cpu was actually used during the run. But it doesn’t influence benchmark results. Not sure how exactly to use it for doing subsequent runs and comparing final performance. Then this needs to be extrapolated to final performance in production.

by spockz

12/9/2025 at 7:58:17 AM

Yeah, what you want to know is which change caused the slowdown, or maybe improved the performance and reasonable metric behind it (for example frame-rate for a game, or something like this).

by malkia

12/7/2025 at 4:32:18 PM

What are folks using for perf testing on JVM these days?

by esafak

12/7/2025 at 5:46:22 PM

For production systems I use flight recordings (jfrs). To analyze I use java mission control.

For OOME problems I use a heap dump and eclipse memory analysis tool.

For microbenchmarks, I use JMH. But I tend to try and avoid doing those.

by cogman10

12/7/2025 at 9:28:37 PM

I use jmh for micro benchmarks on any code we know is sensitive and to highlight performance differences between different implementations. (Usually keep them around but not run on CI as an archive of what we tried.)

Then we do benchmarking of the whole Java app in the container running async-profiler into pyroscope. We created a test harness for this that spins up and mocks any dependencies based on api subscription data and contracts and simulates performance.

This whole mechanism is generalised and only requires teams that create individual apps to work with contract driven testing for the test harness to function. During and after a benchmark we also verify whether other non functionals still work as required, i.e. whether tracing is still linked to the right requests etc. This works for almost any language that we use.

by spockz

12/7/2025 at 4:53:55 PM

jmh is what I've always used for small benchmarks.

by noelwelsh

12/7/2025 at 7:56:02 PM

async-profiler

by gavinray

12/7/2025 at 4:44:39 PM

The only issue I have with Scala 3 is Python envy, they should not have come up with a second syntax, and pushing it as the future.

If anything is slowly down Scala 3 is that, including the tooling ecosystem that needs to be updated to deal with it.

by pjmlp

12/7/2025 at 4:59:57 PM

As a former Scala fan, wow you aren't kidding, wth

    val month = i match
        case 1  => "January"
        case 2  => "February"
        // more months here ...
        case 11 => "November"
        case 12 => "December"
        case _  => "Invalid month"  // the default, catch-all
    
    // used for a side effect:
    i match
        case 1 | 3 | 5 | 7 | 9  => println("odd")
        case 2 | 4 | 6 | 8 | 10 => println("even")
    
    // a function written with 'match':
    def isTrueInPerl(a: Matchable): Boolean = a match
        case false | 0 | "" => false
        case _ => true

by gedy

12/7/2025 at 5:30:46 PM

It's been a while since I touched Scala but wasn't that a thing in previous versions, minus the braces not being present?

by jfim

12/7/2025 at 7:39:13 PM

Yes, that's all just as it was, and in places braces were not required / interchangeable so this is more of an optional compiler choice than a real change

by weego

12/7/2025 at 9:29:59 PM

Sorry, I'm coming from C++-ish background - can anyone explain what's going on :)

by malkia

12/7/2025 at 10:25:08 PM

Scala 2's syntax is mostly Java/C-style with a few peculiarities.

Scala 3's optionally allows indentation based, brace-less syntax. Much closer to the ML family or Python, depending on how you look at it. It does indeed look better, but brings its share of issues.[1] Worse, a lot of people in the community, whether they like it or not, think this was an unnecessary distraction on top of the challenges for the entire ecosystem (libraries, tooling, ...) after Scala 3.0 was released.

- [1] https://alexn.org/blog/2025/10/26/scala-3-no-indent/

by hocuspocus

12/9/2025 at 9:07:36 PM

Just for context, a lot of people in the community think that this syntax change was the best thing that happened to Scala since its inception.

Also the silent majority thinks that the people who still lament over that change are just a very vocal minority.

Almost all Scala 3 code uses the new syntax, no matter how loud a few people cry. Similar situation to systemd on Linux…

by still_grokking

12/7/2025 at 11:57:03 PM

My personal take is this would be like JavaScript adopting an optional Coffeescript[1] syntax. It's so different that it seems odd to make it an option vs a new language, etc.

[1] https://coffeescript.org/#introduction

by gedy

12/7/2025 at 5:06:51 PM

madness :)

by bdangubic

12/7/2025 at 5:21:50 PM

Can you eli5 the madness? And how that relates to python/java?

by a24j

12/7/2025 at 7:16:40 PM

Everything is up to date with the new syntax as far as I'm aware. Also, the compiler and scalafmt can rewrite one to the other. A project can pick whatever style it wants and have CI reformat code to that style.

by noelwelsh

12/8/2025 at 1:08:52 AM

> Everything is up to date with the new syntax as far as I'm aware.

The Eclipse plugin isn't, and none of the newer IDE integrations is reliable.

by lmm

12/9/2025 at 8:56:49 PM

There's still a working Eclipse plugin? Does Eclipse now support LSP servers?

The most reliable Scala IDE is currently Metals (in VSCode, but other editors work, too). Metals uses directly the compiler for all code intelligence so it's as reliable as the compiler itself.

https://scalameta.org/metals/

https://scalameta.org/metals/docs/#editor-support

by still_grokking

12/10/2025 at 1:14:03 AM

> There's still a working Eclipse plugin?

For Scala 2, yes, or there was the last I looked. Still the best Scala development experience by some margin, sadly.

> Metals uses directly the compiler for all code intelligence so it's as reliable as the compiler itself.

Not my experience; maybe it theoretically should be but the integration/bridging piece is still flaky.

by lmm

12/15/2025 at 12:00:55 AM

> or Scala 2, yes, or there was the last I looked. Still the best Scala development experience by some margin, sadly.

I can't find it.

Could you link to that "best Scala development experience by some margin"?

All I know is that the Eclipse plugin is dead since about one decade. But maybe I just missed something.

> the integration/bridging piece is still flaky

What concrete issues do you have?

I'm using Metals on a daily basis and don't know about any such problems.

Could it be that the last time you've seen Scala (if you actually ever seen it at all) was about 10 years ago?

The discussions here on HN regarding Scala seem always massively dishonest, with a lot of people always spreading outright FUD for some reason I don't understand…

by still_grokking

12/7/2025 at 8:11:29 PM

When I checked a year ago, the IDE tooling still wasn't quite there.

by pjmlp

12/7/2025 at 9:31:14 PM

What I don’t get because there is LSP and BSP support. What else is needed to get support for scala 3 from an IDE? Obviously, Kotlin coming from Jetbrains will make it receive a lot more love and first class support.

by spockz

12/7/2025 at 10:21:26 PM

Parity with Scala 2 development experience, which was lacking a year ago.

by pjmlp

12/8/2025 at 5:40:16 PM

With Metals the Scala 3 development experience is better; plus one is no-longer tied to one specific IDE.

by theCodeStig

12/9/2025 at 8:58:14 PM

What are you missing currently?

by still_grokking

12/8/2025 at 2:28:36 AM

I always find downvoting on stuff like this perplexing. It still isn't there. I know that a lot of Scala people are doing metals and some kind of text editor experience, but if you've used something as powerful as Intellij, the Scala 3 experience is a serious downgrade, and it still is today, even though it's better than it was a year ago.

by blandflakes

12/8/2025 at 3:05:11 AM

It's on brand for Scala to have multiple ways of achieving the same thing.

Now we x2 by having the curly brace syntax and the indent syntax.

by ergocoder

12/7/2025 at 5:22:58 PM

You could also have compared it, more attractively, to Haskell.

by esafak

12/7/2025 at 5:47:47 PM

Except the reason behind the syntax change is the losing mindshare from Scala into Python, after its relevance in the big data wave that predated the current AI wave.

Nothing to do with Haskell, even if it is also white space significant.

by pjmlp

12/7/2025 at 10:49:55 PM

It's quite impressive that you can swap out major version from under running application and have just one subtle issue.

by scotty79

12/9/2025 at 9:29:22 PM

The upgrade Scala 2 -> 3 is usually super smooth. The compiler does all the work, you just need to update your build config / dependencies.

The only exception is macros: If you used the experimental Scala 2 macros you need to migrate them to the new system which is completely different.

by still_grokking

12/7/2025 at 8:34:51 PM

Awesome language, nice to see others using it.

I can thoroughly recommend it. Once of the best languages out there in terms of expressive power.

by esarbe

12/7/2025 at 5:23:50 PM

The takeaway of upgrading your libraries when upgrading major language and framework versions applies beyond Scala. Especially when the libraries abuse magic language features (and far too many Scala libraries do) or otherwise integrate deep into the framework/language.

by Kwpolska

12/9/2025 at 9:17:17 PM

> Especially when the libraries abuse magic language features (and far too many Scala libraries do)

Would you mind to explain what you mean?

by still_grokking

12/10/2025 at 5:23:38 PM

The library that caused breakage for the OP is a good example: https://github.com/softwaremill/quicklens

by Kwpolska

12/14/2025 at 11:43:47 PM

I still don't get what you want to say.

Linking some GitHub repo does not explain anything.

What is "abuse", what is "magic" in this context?

by still_grokking

12/7/2025 at 8:22:37 PM

I know this topic has been beat to death but this is another example of why high level language with super optimizing compiler has had less industry success.

If performance is a feature it needs to be written in the code. Otherwise it implicitly regresses when you reorder a symbol and you have no recourse to fix it, other than fiddling to see if it likes another pattern.

by groundzeros2015

12/7/2025 at 8:31:37 PM

To be fair, it’s misleading to group Scala (or any JVM language), with other “high-level languages.”

The JVM is extremely mature and performant, and JVM-based languages often run 5x (or more) than non-JVM high-level languages like Python or Ruby.

by alberth

12/7/2025 at 8:34:43 PM

That doesn’t follow. Scala is a high level language and compiler above the JVM. The bug here is a high level one:

> Turns out there was indeed a subtle bug making chained evaluations inefficient in Scala 3

I’m comparing with Haskell, Scheme, or even SQl which all promise to compile efficient code from high level descriptions.

by groundzeros2015

12/7/2025 at 11:32:41 PM

The bug in TFA is hardly a reason that Scala is not a success, though.

by blandflakes

12/7/2025 at 11:56:28 PM

I didn’t say that. I’m highlighting a specific challenge of getting predictable performance over the lifetime of code.

Lower-level languages don’t have this same problem to the same extent. They have other problems Scala doesn’t have.

by groundzeros2015

12/9/2025 at 9:26:32 PM

> Lower-level languages don’t have this same problem to the same extent.

Of course they have.

If the computer would directly execute what you write down in what you call "low level language" this would be slow as fuck.

Without highly optimizing compilers even stuff like C runs pretty slow.

If something about the optimizer or some other translation step of a compiler changes this has often significant influence on the performance of the resulting compilation artifacts.

by still_grokking

12/12/2025 at 6:51:52 AM

They absolutely do not. The problem is three-fold.

1. The rules for when an optimization works and doesn't is complex and implicit (as seen in this post).

2. The magnitude of performance between getting an optimization and not is significant.

3. When it does fail, you have almost no recourse because you can't express your intent.

Now do C. You have problem 1, but not to the same extent. In rare cases you can see problem 2. And you never have problem 3.

by groundzeros2015

12/14/2025 at 11:41:40 PM

First of all nothing in the article is about optimization. Scala does not even have an optimizer…

It was about translation strategies and macro expansion.

But this makes no difference. You have all issues you just named exactly the same in so called "high level languages" as you have in C. C is in fact a high level language, and the code you write in C has not much in common with what the machine actually executes. The last time this wasn't like that is about 40 years ago.

1. Whether the C optimizer kicks in or not is pure dark magic. Nobody can tell from just looking at the code. The optimization techniques are way too complex to be understood ad hoc, not even experts can do that.

2. The difference between the optimizer doing its work, or instead the computer just verbatim executing whatever someone written down is hilariously large! Adding -O2 can make your code many orders of magnitude faster. Or it does almost nothing… (But like said, you can't know what will happen just from looking at the code, that's point again 1.)

3. You neither can express what the machine does in C. The machine does not execute anything like C. The last time it did is over 50 years ago… Since at least 30 years we have kind of JIT compiler in the CPUs which translate the result of compilation to ASM into the actual machine language. A modern CPU needs actually to emulate a computer that still works like a PDP-11 to match the C machine model even the real hardware does not look anything like a PDP-11 any more! You have only very indirect influence on the actual machine code when writing C. It's mostly about forcing the CPU internal JIT to do something, but you have no control over it, exactly as you don't have control over what for example the JVM JIT does. It's the exact same situation, just a level lower.

by still_grokking

12/8/2025 at 12:36:22 AM

I'm on Spark Scala 2 project and I hate it. Basically any good Scala dev would never want to work on our ETL projects, so we get second rate Python or Java devs like me who bastardize the language to get anything to work. Most of our new stuff is all pyspark, hopefully we can replace Scala asap.

by rr808

12/9/2025 at 9:35:05 PM

What's so bad about it?

Why not try to learn it for good?

by still_grokking

12/7/2025 at 6:15:49 PM

Controversial opinion: Scala should have gone into maintenance mode a decade ago. They got the language right at the beginning, and a decade of tinkering has just fatigued everyone and destroyed any momentum the language once had.

by phendrenad2

12/7/2025 at 6:34:35 PM

> and a decade of tinkering has just fatigued everyone and destroyed any momentum the language once had.

it's hard to buy it, considering that many of those "fatigued" moved on Kotlin, led by their managers' bs talking points.

by instig007

12/7/2025 at 10:00:49 PM

Many of the Scala projects got people fired. Something the Scala devs largely ignore. Plus Scala support is truly awful even by the low standards of an OpenSource project. Then there is the fact that the Scala specific libraries are largely dead.

Scala had/has a lot of promise. But how the language is marketed/managed/maintained really let a lot of people down and caused a lot of saltiness about it. And that is before we talk about the church of type-safety.

Scala is a more powerful language than Kotlin. But which do you want? A language with decent support that all your devs can use, or a language with more power but terrible support and only your very best devs can really take advantage of. And I say this as someone writing a compiler in Scala right now. Scala has its uses. But trying to get physicists used to Python to use it isn't one of them. Although that probably says more about the data science folks than Scala.

PS The GP is right, they should have focused on support and fixing the problems with the Scala compiler instead of changing the language. The original language spec is the best thing the Scala devs ever made.

by hunterpayne

12/7/2025 at 11:03:07 PM

Kotlin has become a pretty big and complex language on its own so I'm not sure this is a good counterexample.

The fundamental issue is that fixing Scala 2 warts warranted an entirely new compiler, TASTy, revamped macros... There was no way around most of the migration pains that we've witnessed. And at least the standard library got frozen for 6+ years.

However I agree that the syntax is a textbook case of trying to fix what ain't broke. Scala 3's syntax improvements should have stuck to the new given/using keywords, quiet if/then/else, and no more overloaded underscore abuse.

by hocuspocus

12/9/2025 at 9:44:52 PM

> However I agree that the syntax is a textbook case of trying to fix what ain't broke.

The great new syntax is the very reason I don't want to even touch Scala 2 any more.

The syntax change is the absolute highlight in Scala 3. It makes the language so much better!

The only real problem was that it happened so late; at least a decade too late.

by still_grokking

12/7/2025 at 11:35:07 PM

One impressive thing for us is that the changes to macros were hardly an issue. We'd been trending off macro-heavy libraries for a while, and our Scala 3 adoption has not really been harmed by the new macro system.

by blandflakes

12/9/2025 at 9:41:39 PM

> The original language spec is the best thing the Scala devs ever made.

The overreaching majority thinks that Scala 3 is objectively much better than Scala 2 ever was. That's at least what you hear just everywhere, besides the occasional outlier by some Scala 2 die hards.

by still_grokking

12/8/2025 at 1:12:21 AM

> Scala had/has a lot of promise. But how the language is marketed/managed/maintained really let a lot of people down and caused a lot of saltiness about it. And that is before we talk about the church of type-safety.

On the contrary, there was nothing wrong with Scala's marketing. What's damaged it is a decade of FUD and outright lies from the people marketing Kotlin.

by lmm

12/9/2025 at 9:36:43 PM

Sure. All successful languages go into decades still stand.

Just see how great this worked out for Java (or Perl… ;-))!

/s

by still_grokking

12/7/2025 at 4:25:04 PM

Thank you for sharing. Interesting insight on dep libraries.

by atbpaca

12/7/2025 at 5:34:32 PM

I’m not familiar with Scala’s macro system, but it seems like a big takeaway here is: Be careful with code that invokes the compiler (JIT) at runtime. That seems like it’s asking for trouble.

by munchler

12/7/2025 at 6:34:50 PM

Macro's are compile time, there is no runtime codegen.

The problem was overly-frequent inlining generating enormous expressions, causing a lot JIT phase and slow execution.

by dtech

12/7/2025 at 6:43:12 PM

Thank you for the clarification. If I understand correctly, these large expressions are created at compile-time, but the impact isn't felt until JIT occurs in the runtime environment. In that scenario, shouldn't the JIT just run once at startup, though? I'm still not quite understanding how JIT can take so much time in a production environment.

by munchler

12/7/2025 at 9:53:55 PM

Because the jit will let the unoptimized code run a few (hundred) times to take measurements to know what needs to be optimized and how it needs to be optimized. This is a good solution and makes hotspot very effective. The problem is that it happens randomly a few minutes/seconds into the operation of the service. So you randomly have a big pause with the performance hit everytime you run the service. The upside is that this only happens once. But you have to plan for a big performance hit to requests which are unlucky enough to be called at the wrong time.

by hunterpayne

12/7/2025 at 10:30:44 PM

And this can generally be avoided as well, by doing "warmup" when starting your service (effectively, mock some calls), but before accepting requests.

by pretzellogician

12/7/2025 at 10:56:30 PM

Of course, but then you have to actually do this. It is just another complexity to add. Also, I was answering a question about the hows and whys of the jit. I wasn't saying it was impossible to work around.

by hunterpayne

12/8/2025 at 12:55:08 AM

Ah, that’s interesting. I wasn’t aware that JIT-ing will do that sort of performance analysis first. Thank you for the explanation.

by munchler

12/9/2025 at 9:50:36 PM

It won't in general.

Doing so is a feature of high-end VM runtimes like the state of the art JVMs or JS runtimes.

by still_grokking

12/7/2025 at 9:17:52 PM

That's not true, Spark's entire query engine relies on use of runtime codegen via macros/quasi quotes

Look up the architecture of Catalyst + Tungsten

https://www.databricks.com/glossary/catalyst-optimizer

by gavinray

12/8/2025 at 1:10:14 AM

Catalyst uses runtime codegen, sure, but the OP wasn't using that.

by lmm