When is scala the right tool for the job?

Scala is an excellent choice for building highly scalable, low-latency, multithreaded applications. It has strong typing, a concise syntax, and a highly functional design. It's especially good for building long-running services, and at solving problems with strongly-defined data structures and a lot of concurrency. With the addition of tooling like Akka or ZIO, it also becomes an especially good choice for streaming applications, event-driven applications, and more.

There are plenty of times when Scala is not the right tool for the job, however, and in this article we'll discuss some of the best use cases for Scala, along with some poor ones. We'll also look at some of the dangers of "language purity" and how picking the right tool for the job, and adding more skills to your skillset, can make a more effective developer.


Pros and cons of Scala

So let's take a look at some of the strengths and weaknesses of Scala. These are not exhaustive, but stand out as some of the most fundamental aspects of the language.

Pros

Cons

Many attempts have been made to partially mitigate some of these negatives of Scala, with varying degrees of success. Giter8 templates can be used to quickstart a project, or an IDE can do some of the lifting for you. Ammonite attempts to allow simple scripting in Scala to be more viable by allowing single-file .sc scripts to be run; under the hood, it builds and caches the result, including an additional syntax for declaring dependencies inline. What it does even better, is provide an excellent REPL interface for experimenting with Scala. While I would avoid using Scala as a scripting language, I do recommend the Ammonite REPL for quick experimentation. GraalVM is an alternative to the JVM which has much faster start up time. ScalaJS compiles Scala into javascript, making it possible to write Scala which will run in a web browser. Each of these solutions have their own downsides, however, and can't make Scala the equal of languages or tooling better suited to these kinds of problems.

Considerations and use cases

With the pros and cons in mind, let's consider some factors which might inform whether Scala is the right choice for your application.

High concurrency

Scala really shines in its safe and fast handling of concurrency using functional principles. If you're writing a low-latency, highly concurrent application, Scala is an excellent choice. For basic application designs, you can use the Futures API to handle concurrency. For larger or more complex designs, you can consider whether your application would fit well with an actor system model and consider Akka, or whether data streaming fits your use case and consider Akka stream or ZIO Streaming designs. These libraries can make designing a concurrent application much easier from a top level down, as I discussed recently in a case study of using Akka actors.

If you don't need high concurrency, you may not be making full use of the advantages of Scala, and considering other tooling may be worthwhile. This may also mean that the most complex or highly concurrent pieces of your architecture should be written in Scala, particularly with tooling such as Akka, but other components could benefit from the advantages of a more basic design in another language. For example, it's common to see Scala backend services supported by a Python or NodeJS middle-tier layer in web applications.

Data variability

Scala is great at modelling data by providing strong types and case classes to fit the shape of your data. This gives you a lot of compile time guarantees about how you're using the data, and is great if you know the shape of the data at compile time. This doesn't mean the data has to have a small number of fixed shapes, though; Scala is also good at modelling optional and multi-shaped data and other complexities.

If your data is highly variable, specifically if you only know the schema to which it conforms at runtime, Scala may not be the best choice. While it's always possible to interpret your schema at runtime using libraries, if this is the primary purpose of your application, a dynamically-typed language is likely a better fit.

Project size

While Scala is appropriate for almost any size of project, it's worth considering the minimum start up cost in terms of initial setup for development and the speed at which development can take place. As Scala aims to provide strong compile-time guarantees and a large degree of runtime safety, it means a well-written and well-tested project can scale up to any size with little to no loss of confidence. The trade off for that confidence is that it typically takes longer to develop than a similar application in dynamic language.

Similarly, Scala has a lot of useful tools, but many of them aren't part of the standard library and require dependencies, and decisions to be made early on – for example, the large number of possible JSON libraries in Scala, and the range of different toolkits you might consider using.

So, consider where your application lies on the "build it fast" vs "guaranteed uptime" curve when choosing whether Scala fits. To quickly create prototypes or proof of concepts, you might instead reach for a dynamic, language like python. It may later be appropriate to take the slower but more solid approach of replacing it with a Scala service – with better concurrency handling, better scaling, and better type safety.

Scripting

I'm including this section as a focus on day-to-day DevOps / development work, as I've found it common for Scala developers especially to have a certain tunnel vision or language purity with Scala. I've seen this result in developers either attempting to automate development tasks using Scala and doing so slowly and/or poorly, or giving up and doing a menial task repeatedly because they can't figure out how to elegantly automate the task in Scala. Generally, this degree language of language purity is counter-productive.

I'm a strong advocate of learning new skills and using the right tool for the job. While my specialty is Scala, it's important to be able to use one or two other languages to cover the gaps in which Scala does a poor job, especially since scripting simple tasks to speed up development is something any developer needs, and something Scala does poorly.

For me, that means having a good grasp of Bash and Python alongside my expertise with Scala. Bash is often feared as being old, clunky and a bit arcane, but at least a grasp of using the terminal is vital for any developer. Being able to take that one step further and automate simple tasks, especially related to working with files or making simple HTTP calls with curl, can make your life easier even without requiring more than basic understanding of Bash. For slightly more complex scripts, perhaps working with pieces of JSON, making more complex HTTP calls, or using one of many libraries, good grasp of a scripting language is also important. I choose python due to its simple and concise syntax and famously broad and easy toolkit, but Perl, Ruby, JavaScript, and others can fill the same role according to personal preference.

To provide some extreme examples, this once led to me rewriting someone's 700-line overly complicated Scala "script" which had been incorporated into a unit test file but prevented from running as a test, instead requiring you to uncomment some lines of code, replace URL and data payload variables, and run from a specific line from inside an IDE, with the result of writing some arbitrary data over TCP to a backend service. Using python, this became a 15-line script which could accept an arbitrary JSON payload and command line parameters like write-payload --host example.com -f /tmp/data.json and be used across several different projects.

Similarly, a standard part of the testing procedure in another project involved using a GUI application to manually perform a series of 10 steps, taking approximately 10 minutes multiple times a day, because it was non-trivial to automate. This process was being followed by half a dozen developers and QAs. A couple of hours of digging into the process and writing some python, and the whole team could eliminate that process entirely going forward.

In short: a good developer needs some working knowledge of DevOps, and at least some proficiency in scripting to perform such tasks. To avoid beating a dead horse, I leave you now with my public collection of useful scripts as inspiration for some of the types of jobs I've found worth automating in the past.

tl;dr

In summary: