- Safe and high performant concurrent programming. Scala is miles ahead of most other languages here and pretty much on par with the best ones (such as Haskell)
- ETL / data transformations. Python is a big player here - but for stable and performant data pipelines, I strongly believe Scala is the better choice. For explorative things, python has the edge though.
- Actor systems on the JVM. I believe that most "scalable" systems are over-engineered. A well configured postgres / elasticsearch and a machine with your application on good hardware goes _very_ far. But sometimes it's not enough and then Scala offers a great solution with Akka on the JVM. Erlang/Elixir with their runtime are probably even better, but Scala offers the better typesystem and one can stay in the JVM world if they want.
- in-language custom DSLs. No seriously, Scala is the best language I know in terms of building typesafe, customizable DSLs within the language, making it almost look like another language. This is great if not so techy folks are to make changes to actual code in an easy way. The link in this post here shows some examples but it goes beyond.
- Writing glue-code. Surprisingly, I think Scala is better than python and many other languages here, because of the sheer power of composability of the language and ways to connect pieces with each other in a typesafe manner. The reason for this lies mostly in the concept of implicits, which both enables great power and reusability but also makes the learning curve much steeper.
This list might be a bit subjective and I don't know every language out there, but as the questions comes up almost everytime, I wanted to list the strengths of Scala in the areas where most other languages can't compete with it.
Note, I spent around 5 years working with Scala full-time and grew a profound aversion for the language and its ecosystem. It definitively affects my judgment. I found in Rust all the "good parts" of Scala minus the things I resented.
I can write my React/JS front end [1] and highly concurrent, real-time scalable backend [2] using the same language, build tools etc.
[2] http://zio.dev
I disagree. And I've done a lot of Scala ETL work. The issue is that in Scala ETL work your data structures are either untyped (Spark Dataframe), case classes or typed tuples. If they're untyped then there's little to gain from Scala vs. Python in terms of type safety and a lot of overhead. If they're case classes then you're moving around a lot of unnecessary data fields and you've got the overhead of making fifty intermediate case classes yourself. If it's typed tuples then it's on you to remember which field is what as nothing is named.
Some sort of intelligent compile time case class subset generation would have helped the situation immensely. I think frameless (https://github.com/typelevel/frameless) gives you that power but it's a lot of shapeless black magic overhead and I've never seen it used in production (and probably various maximum field limitations and much slower compile times).
edit: Case classes also have (or had) a steeply increasing compile time memory requirement as you add more fields which is fun when your data is 200+ fields long. Almost as fun as having to make a 200 field case class to read in a single file of which you only need 50 fields but want to be type safe.
edit2: Scala is popular in ETL because the Hadoop ecosystem is JVM and Java used to be atrocious. So Spark (which wanted Hadoop compatibility) picked Scala because it was better than the alternatives. However nowadays Databricks is investing a lot more into their Python support from what I can tell and there's Python native competitors out there (Dask, Ray, etc.).
Haskell developer here... What about case classes and lenses? Do they solve this?
From my experience, auto-complete for Python shows everything (like JavaScript's), so I end up googling.
But yeah, I get your point, I find it annoying too.
Though, I am curious if there is anyone else who shares my mindset on Scala.
In a corporate environment, I found it to be an extremely expressive and powerful language but that power comes at a grave price, which I'll try to summarize:
- it's difficult to understand other people's code compared to other languages (e.g. Go) - it's so very implicit that you end up having to hold a lot of state in your head to understand what's going on. - the language is basically impossible to read effectively without IDE features.
I usually enjoy reading most code bases, but Scala is downright painful to read in plaintext. You end up having to be a compiler.
IMO modern language designers should be making IDE-first languages - after all, most serious programmers do use IDEs (even if they build that IDE within Emacs or Vim). The problems with "visual languages" are that without a textual representation you can't meaningfully diff/merge/blame, not that using the GUI is an inherently bad idea. With Scala you get the best of both worlds: it's textual enough that version control works properly, but you have standard-ish way of folding, hovering etc. that mean that you can "zoom in" on the details of unfamiliar code but also "zoom out" to get a clear overview, in a way that few other languages manage.
If I can't understand the type of a route (or a db-query) because it's a 5-level nested type, how am I going to write a function that takes one as a parameter?
</rant>
Because, once I got used to the (pure) functional programming style, I found it more difficult to mix this style with imperative code. It's almost always easier to for example use for example the state monad than writing it with mutation. This is probably quite subjective and it depends what you are used to.
For me, I make an exception for tests. E.g. when I mock my key-value database with an in-memory map, I choose a mutable map. But I know that some people prefer FP style even for tests.
I wouldn't use the word "state", since that has connotations that implicits are somehow changing at runtime. It's certainly true that scope is much more important and non-obvious than explicit variable names.
Type aliases can also get in the way when thinking about implicits (e.g. we might want an implicit 'Foo[Bar]', but if those are aliases then the compiler might start chaining Maps of Lists of Strings of whatever to resolve it).
Implicit conversions definitely seem like they could cause headaches (e.g. performing 'String' operations on a 'List[Char]' and having it implicitly and silently converted). I've only been using Scala for the last year, and thankfully implicit conversions seem to be avoided these days!
I'm no stranger to diving into a new codebase and trawling my way through spaghetti to make sense of it ... but I absolutely do not want to do this with a Scala codebase ever again.
I think it depends a lot on the code. Scala 2 gives you a lot of guns to shoot yourself in the foot (see: implicit, as discussed here) - but you can also use it in its mostly-functional form, with immutable values, and then it can become very readable. Granted - I've always been using IntelliJ but I could read the scala code on Github too, just fine.
Oftentimes one stares at a mile-long chain of methods on a list and is left wondering "exactly what did the original author want to do here, and why are things breaking"? In the end, the only way to find out part of the answer is to exercise the relevant codepath via some test data (if you're lucky) and use IntelliJ's excellent debugger to help you move forward. Even this just reveals the "what", not the intent.
No amount of consistent linting or formatting can make this better. And no, ExpressivelyVerboselyNamedFunctionsInAidOfSelfDocumentingCode don't help either.
Scala is a beast and the package manager + build tools were giving me headaches. I’m optimistic about the current trajectory with Scala 3 and simplifying the language.
Ignore them and use maven. It's much better documented, consistent, and backwards-compatible. I struggle to understand why SBT ever gained any popularity, and it should certainly have never been recommended to newcomers.
Once you start to dig deeper, you find out that setting multimodule projects is still easier in SBT. And if you decide to dig deep and really learn the build tool, it doesn't really matter which one you choose. But devs that chose SBT as their Scala build tool will probably keep using it.
This is the type of stuff that made me go away from Scala.
Why implement a feature that optimises for code writing? How does my editor let me know that function receives that parameter without me going "???" and having to go into its definition?
Implicit conversions fall into the same category, of making code pretty to look at, quick to write, and a nightmare to understand when you're new to a codebase.
Shame, really. The good parts of Scala are wonderful.
Every real-world Java codebase ends up using massive amount of incomprehensible magic for e.g. DI, transaction management, web request mapping, serialisation. Every real-world Python/Ruby codebase ends up using magic proxies, metaclasses, method_missing or other such stuff. Scala is the only language where I've been able to find real, enterprise-scale codebases written in 100% plain old code without any AOP-style magic, because the implicits let the language be expressive enough that you can avoid those things without your business logic getting drowned in secondary concerns.
IntelliJ has been able to do that for a while now.
> Implicit conversions fall into the same category, of making code pretty to look at, quick to write, and a nightmare to understand when you're new to a codebase.
Don't do it, and don't allow it in your codebase.
It has been 4 years since I did Scala everyday, back then it was hit or miss. Good to know things have improved.
> Don't do it, and don't allow it in your codebase.
I get your point, but that doesn't solve the issue if the community is down for using these features.