Why did we use Scala as our main backend language?
Given what we needed to accomplish when we founded TrueAccord – and how we intend to grow – Scala quickly emerged as our ideal programming language. From its interoperability with Java to its emphasis on functional data structures and economy of code, Scala has delivered an incredibly versatile engine to power TrueAccord’s Proactive Loss Management system for recovering debt portfolios worth tens of billions of dollars.
Of course there are solid arguments for a range of programming languages. Java may seem the obvious choice, given its popularity and the breadth of its libraries. But many developers rate Java pretty low on the fun scale. There’s the ever-popular Python and Ruby, which many feel are optimum for the front end, but we wanted to use a single language for the entire stack.
We actually started in Python, because our core team was very familiar with it. Python allows you to get off the ground really fast, but as the code grew and more people joined the team, Python’s lack of type safety started to slow us down. Despite our disciplined unit testing, things got messy very quickly. It took quite a bit of reasoning to be completely sure what each function expected as arguments and what it returned. Ultimately we realized we needed something that would make it easy for us to write robust, maintainable and type-safe code without hindering the team’s productivity. Scala was the answer.
Interoperability with Java
Scala allows us to access Java’s huge ecosystem. Java has been around enterprises for a long time, and there is a wide variety of high-quality libraries for any imaginable functionality. From essential libraries like Joda-Time to the handy utilities in Apache Commons, Java has it covered.
It’s also very common to see third-party service providers like payments processors provide Java libraries that access their APIs, which saves us hours of integration work and makes it easy for us to quickly experiment with many platforms. This is how TrueAccord is able to personalize correspondence with individual debtors and make it easy for them to pay creditors via a number of different methods. On top of that, the JVM provides a robust environment to run our code. There’s a variety of parameters we can tune and many tools available for monitoring, artifact deployment and so on. As Scala runs on top of the JVM it enjoys this rich and mature ecosystem.
Functional data structures
When you are writing non-trivial computations, especially in a multithreaded environment, it’s easy for things to go awry. In languages like C and C++ it’s common to have a state that is shared between different threads. When you go that route, you have to be careful about using locks or mutexes around each access to the state to ensure that no two threads can modify this state at the same time. It’s very easy to make mistakes in this regard. Scala encourages writing pure functions that manipulate immutable data structures. When your data structures are immutable, you can freely share them between different execution contexts, and deadlocks and race conditions become things of the past.
Economy of code
Scala is a very expressive language. And yet it lets you express your ideas with very few lines of code. When you define a case class, you are actually communicating a higher level abstraction that relies on other types.
For example, a Person could be a case class that consists of a name, age and an address. The address could be another case class with fields like street, city and zip code. By defining types in this way, usually in one or two lines of code, Scala provides a functionality that is equivalent to 20 to 30 lines of Java code. The savings here comes from not having to implement constructors, getters, equals() and hash() methods. There are many other examples like this that allow the Scala programmer to write fewer lines of code that say quite a lot. This leads to fewer bugs and less code to read and review.
This is not to say there are no drawbacks. Like any technology, Scala is not perfect. For example, Scala code that uses functional programming idioms can be a little confusing to newcomers, but you get better at reading and writing functional code with practice. It’s the same as lifting weights to build muscle. Another drawback is the compilation time. It can take a little while for the compiler to go through a full build, but on the other hand, having immediate feedback from the compiler on mismatching types and other common human errors helps recover that lost time.At TrueAccord, this level of code correctness saves us invaluable time and money in the long run.