Yes, Java has been getting a lot of features Scala has had since (more or less) always. But it's a continuing process, and not all such features are yet fully fleshed out and polished in Java.
Also, Java will probably never get many of important features Scala has (or will have). It may not be some esoteric things, like higher-kinded types. But things like meta-programming/macros. Or features which may be advanced from theoretical point of view, but are actually easy from user point of view (because they lead to a simpler code), like Capture Catching.
If capabilities (Capture Catching) proves to be very useful (and really solves the problems it claims to be able to solve) then it's likely that Java will also implement it, no? So... in about 8-15 years?
I doubt it. For Capture Catching of Capabilities to work, you need some of the unique sauce practically only Scala has. E.g. Contextual functions or path-dependent types. Java almost certainly won't adopt these.
> > Another common request is to “stop implementing features”.
> Yes, it's a very common one shared by virtually all Scala 3 developers. Stop. At least for a couple of years.
I, for one, think Capture Catching can't arrive soon enough. It will allow us to write much simpler programs, getting an edge over modern Java & co. I'm very much looking forward to it.
Don't use experimental Scala features in production code. They may change or be removed. And they will likely lack support in IDEs. But that is a common sense.
Thankfully not anymore. They got their act together and have been maintaining compatibility since Scala 3.0.0 has been released in May 2021, which is almost 4 years and counting.
In my opinion the tooling like sbt, scalafmt, ... is actually semi decent, but the LSP is a pain to use.
The only way I'm productive on scala is on Intellij, as soon as I have to even glance at the metals LSP implementation my productivity skydives
This is compounded by the fact that most good AI editors are based on VSCode, which means I either have to suffer through it, or alt-tab to intellij any time I want to edit code
* Immutable/persistent collections in standard library
* Machinery to "modify" immutable deeply nested case classes/sealed traits. You have the copy method, you have lens libraries. Very easy and comfortable to use.
* Expression oriented. if/try/etc expression can be bound to a variable
* less characters to write the same idea/program, while not losing readability
* better tooling: Scalafmt is ubiquitously used, supported in IntelliJ and is very good. Scalafix (a linter which can also fix some issues automatically) is used a little bit less, but is also good.
* build tools: while I don't like sbt, Mill is a so much better build tool than Maven or, even worse, Gradle. Then there is also scala-cli, which is not a build tool, but can work like it, if you have a simple, single-module project (i.e. no sub-projects/sub-modules).
Thank you, this captures most of these. I’d also add the excellent libraries from Twitter like Algebird and ability to do a lot of data processing with types at scale using Spark.
And if you want both frontend and portability everywhere, Scala will soon have a support for compiling to WASM (with WASI, etc) https://github.com/scala-wasm/scala-wasm/ (to be integrated into Scala.js after developed)
> And if you want portability, you can compile a Scala program with GraalVM's native-image and statically link everything with musl libc
Getting the musl stuff to work can be tricky, mostly-static (only libc dynamically linked) is an easier option.
I've built a CLI diagnostics app with Scala & NativeImage and I've embedded the Graal Python interpreter inside it to allow extension scripts to be written. The result is a zero-install executable that provides an n entire Python environment. I think that's a good showcase for one of Scala's strengths, it's interoperability with the Java ecosystem.
> If anyone care to share their experience with GraalVM's native-image, I'd be interested in hearing that.
The main issue is if you are using reflection, which needs metadata adding to describe it so the necessary metadata is included in the image. Some libraries already have it built in, and there are tools to help.
Thank goodness that Shapeless is not needed in Scala 3. The good parts have been integrated into the language itself and so it's reliable and faster.
> Jetbrains had completely abandoned Scala
Thankfully not at all. Gets regular releases, Scala 3 support is improving with each. They're also welcoming to PRs, if you have spotted a bug that needs fixing. (The codebase of the Scala plugin is in Scala, so that makes it easy for the community to contribute.)
My company still sticks to Scala2 so I may be misinformed, but I heard Scala3 tuples cannot completely replace Shapeless, like missing LabelledGeneric equivalent?
Java has certainly improved. Kudos to its stewards.
But I think it still has many rough edges -- things that are awkward (or outright impossible) to do in Java and Scala is great. It doesn't have to be advanced features, like meta-programmig/macros. Here are some example that I think are not anything esoteric:
* Just the mere fact that Scala has immutable/persistent collections improves how and what programs people write.
* Scala also has good infrastructure to deal with "modifying" data model graphs in a persistent/immutable way. Think deeply nested case classes and sealed traits. You have the copy method, lens libraries, etc. Java does have records and sealed interfaces, but all the rest of the machinery to work with them is still missing.
* To generalize the points above, Scala is immutable-first language, with all the positives that come with it. Java, still not so much (even though they are moving in that direction, e.g. `record`s).
* Another weird thing in Java is how it deals with variance. In Scala, I find it easy to comprehend, in comparison.
* Scala is expression oriented. Ifs, trys, etc -- all of them are expression. You can bound the result of these expressions to a variable. Not the case in Java, which makes it annoying to work with. You have to fist make the variable null or something and then make sure it gets assigned within of the body of the if/try/... Just a bad experience :(
Than there is a matter of culture:
* Java libraries like to return (and expect to be passed) a `null`. Scala culture embraces `Option` from its standard library.
* While Java does have support for checked exceptions, which I think is a very good idea in theory, in practice its implementation is underwhelming (e.g. not possible to abstract over) and so libraries don't use it as much. With Scala you can return an `Either`. Or with new Scala 3, we may soon have powerful capability system to, among others, allow throwing "checked" exceptions. That's the Capture Checking https://docs.scala-lang.org/scala3/reference/experimental/cc... research.
* This may be even more personal opinion that others, but I find Java libraries more difficult to use that Scala ones. With Scala, you just follow the types and you create and work with the objects that the library gives you in an intuitive way. With Java, the types don't help you as much. You have to read the documentation thoroughly, to make sure you're calling the right methods on the right objects, in the right order. Because the types don't help you, you can't be sure you doing it correctly, because every other way compiles too.
Kotlin may be more popular, but not much. It's nowhere near the mainstream languages like Java, Python, JavaScript, C# or PHP. Not even close to TypeScript.
Kotlin's popularity plummets once you leave out android development, though. Same with Obj-c/Swift for Mac/iOS development.
5-8 years ago Scala had a large boost in data science/big data work as it was either it or Python for a lot of frameworks like Spark. We used Scala because we wanted static typing and threading (among other things) for our workloads.
Huh, fair enough. Maybe my spheres are much more Kotlin-focused and I was projecting too much.
That said, probably "number of Github projects" and/or "number of StackOverflow tags" doesn't encapsulate the sheer amount of code written in Kotlin for Android apps, which is where my head was probably at.
Very interesting. Have you already investigated where is Mill's overhead spent? What can be optimized in Mill to get its time closer to just invoking the javac? Do you already have a plan?
Yes, Java has been getting a lot of features Scala has had since (more or less) always. But it's a continuing process, and not all such features are yet fully fleshed out and polished in Java.
Also, Java will probably never get many of important features Scala has (or will have). It may not be some esoteric things, like higher-kinded types. But things like meta-programming/macros. Or features which may be advanced from theoretical point of view, but are actually easy from user point of view (because they lead to a simpler code), like Capture Catching.