A tryst with Scala

What to expect when starting out

Imagine a scene, with 3-4 new grad. ThoughtWorkers, from a recently concluded university term, aggressively discussing their work preferences as they ponder upon their future at the company. And now imagine one of them saying, “I won’t really want to join that project because.... [insert irrelevant ramblings here].... plus I don’t want to go into potentially weird things like Scala, I want to learn & do more of Java.” I don’t think I’ve made a technically more embarrassing statement in my ever so short stint as a developer. Times have changed immensely since then. It’s been close to 10 months since I started learning and working on a pretty large scale Scala project here at ThoughtWorks. As clear from the above prologue, I was skeptical if not downright hesitant of working with Scala, but never have I been happier to be proven wrong. These past months have taken me on an intellectually satisfying journey that has transformed my way of thinking about programming in general.

For the uninitiated, Scala is a multi paradigm general purpose programming language, that ingeniously attempts to integrate the best of object-oriented and functional programming worlds. It’s a pure bred OO language where every value is an object and every operation is a method call, but at the same time it’s also a full blown functional language with first class functions, efficient immutable data structures etc. Oh, and did I forget to tell you that it runs on JVM? So you also get seamless interoperability with Java and an easy access to years of brilliant work done in that language.

Scala is an acronym for ‘Scalable Language’. Martin Odersky (Scala’s inventor) says it’s scalable, it grows with you. I couldn’t agree more. I’ve found programming in Scala to always be an extremely enjoyable experience. While it may seem very daunting at first with its arcane syntax and various constructs, it is flexible enough to allow you to start as slowly as possible and progress at a rate best suited to you, and I’ve completely loved that. You can start off with writing staid Java or even C-style code, but you can also go on to become embarrassed of that yourself and write more & more idiomatic code. I’ve been told it’s possible to write almost Haskell-like code. I’m not there yet but I can confirm the idea of gradual progress in Scala as I’ve seen my own coding style & abilities transform right in front of my eyes. Although I must admit I was initially taught by the biggest Scala enthusiast I’ve ever seen, so that helped as well, but in general the language makes itself very accessible to someone new picking it up. Basically it allows to you to easily dive as shallow or dive as deep to get your job done.

I mentioned before that Scala changed the way I think about programming in general. Well I’ve another embarrassing little fact to confess. Before starting out with Scala, I was a fan of dynamically typed languages. I actually preferred dynamic typing over static typing. There! I said it. But Hey! That has changed completely over the last few months. One of the things I like the most about Scala is its brilliant type system. When you have a large scale system complete with complex business rules such as ours, types pretty much act like a godsend. They help organize your programs way better than you can without them. One of the very first advantages that I can think of having strong types is that they act as good documentation helping understand program organization and the flow of logic. Also, in my experience, types have saved us from errors that could have potentially creeped up till deployment but the compiler just won’t let them pass. Type safety, FTW!

I still remember the days from my earlier project where we were working with Python and how refactoring would often mean an arduous effort unless you’ve everything safely backed by unit tests. But with its type system acting as an efficient safety net, Scala has provided me with easy yet some of the most fulfilling refactoring experiences. This brings me to the third confession I want to make. We here at ThoughtWorks believe in test driving our code, i.e., to say we like to do TDD, but by now I’ve ditched it completely. I’ve started doing what one of my excellent ex-colleagues introduced me to - Type Driven Development or Type First Development and am absolutely in love with it. It’s as simple as it sounds. You use types instead of tests to drive your design which often starts with assigning types to your skeleton code and then going on to implement it step by step. For those who don’t like the stress of writing types every time every where on their fingers, there’s type inference. But in my experience, unless it’s absolutely trivial, explicit type assignments are preferable over inference. There have been instances where we let inference do its job and it came back to bite us. While I’m still learning it, I find TyDD a good replacement for TDD. Do keep in mind that types are not a replacement for unit tests but only provide an alternative to TDD. Although they do help to reduce the number of trivial unit tests that you would need to write just to ensure type safety in a dynamically typed language.

Another reason I love Scala is because it lets me program more but write less. It does away with almost all of the boilerplate and you only write intentional code. Its case classes are a perfect example of this. Take a look at the below code snippet comparing public class declarations in Java & Scala:

Java:

            public class Test {

            	private int num;
            	private String data;

            	public boolean equals(Object obj)
            	{
            		if(this == obj)
            			return true;
            		if((obj == null) || (obj.getClass() != this.getClass()))
            			return false;
            		// object must be Test at this point
            		Test test = (Test)obj;
            		return num == test.num &&
            		(data == test.data || (data != null && data.equals(test.data)));
            	}

            	public int hashCode()
            	{
            		int hash = 7;
            		hash = 31 * hash + num;
            		hash = 31 * hash + (null == data ? 0 : data.hashCode());
            		return hash;
            	}

            	// other methods
            }
          

Scala:

          case class Test(num: Int, data: String) {
            // other methods
          }
        
See, what I mean?

Scala also lets me write much more concise code. You can pretty safely assume 3-4 lesser lines of code than equivalent Java. The functional constructs and type inference help a lot here. The option of getting rid of dots, semi-colons, parans., & braces unless absolutely necessary, makes your code more readable and hence more understandable. This can be a huge advantage for someone just starting out with the language who'd probably read code written by others as much as, if not more than, writing his own.

scala code Image Credits: toptal

All this is just scratching the surface. Scala has numerous impressive features that do not cease to amaze me. Traits, Pattern Matching, Case Classes, Options, Higher-order functions, Lambdas and many more – I can't do enough justice to them over here but once you've used them, you fall in love with them.

One of the reasons Scala has become so popular is because it makes concurrency painless & easy-sailing. But first let's admit it – Concurrent programming is hard and yet with clock speeds flattening and the number of CPU cores still increasing, it's going to be the norm going forward. There exist very few languages which can achieve it efficiently and not make it a big strain on the programmer. Scala is one of them.

Our project's architecture is asynchronous and non-blocking. I believe it won't have been possible for a complex system like ours to attain that, if not for Scala. We've used Futures & Promises to achieve that.

Although these are no new ideas but Scala with its advanced functional abstractions greatly improves over the similar but dreaded APIs already existing in other languages. I was a complete newbie to concurrent programming before starting out on this project but apart from a few minor glitches here and there which required help from the experts on the team, I've been able to work quite easily with our architecture. Frankly, the business logic in our system still scares me sometimes but not its concurrent architecture and the codebase.

But then, there exist no silver bullets either. Scala, or rather working on a Scala based system, though brilliant, it has its own set of pain-points that might put you off initially. While they have been worked upon and improved recently, scope for betterment still exists.

To start with, compilation speed is excruciatingly slow especially when working on a mammoth codebase like ours. There are ways to get around that to an extent and we've had to take extensive steps in the past to tackle it. We also use a buggy feature of the sbt which allows incremental compilation of our code. It gives us some timing improvements but has also bit us very hard a few times. Then there’s also the sbt which is not so simple as its name might suggest. We’ve had people picking up and having fun with Scala in a few weeks time but still struggling with sbt after months on the project. Our team has also struggled to find a good mocking software for unit testing our code. We use Mockito but using it with tests for our mostly concurrent code is often extremely painful and tricky. Many of us (including I) have spent hours frustrated after getting a functionality up but struggling to finish its tests because the mocks just won’t comply. Apart from these, if you like to use IDEs but don’t own an IntelliJ Idea Ultimate license, you’ll have to suffer while working on a large scale Scala project. Although the community edition of IntelliJ IDEA supports a free Scala plugin but it only supports basic Scala and won't work with any other Scala based framework (for e.g. Play) that you'd need to use on a real project. All in all, you could say that more than the language itself, it’s the tools around it that build negative connotations in peoples’ minds about Scala.

But let none of that disillusion you from trying out Scala. There are flaws in every human invention. It might seem difficult at first but it’s a very powerful tool that you’d return to often once you’ve learned how to use it well. It’s not trivial and yet simple. It’s sophisticated and yet not complex. I’ve personally found it very pragmatic unlike the idealism of Haskell and their ilk or the laziness of dynamic languages.

Personally after having worked with it professionally for many months, I feel its easy to get started with Scala. You can do that over a weekend. It’s also a great language to start off with functional programming. You can do it at your own pace. I like it slow & steady. And this has helped me rekindle my interest in mathematics too. It’s just that there’s so much out there in this brilliant language, that people trying it out often end up frightened. So you must be patient at the start and try and swim in the shallow end of the pool before diving into the deep end because you may drown if you’re unprepared and no one likes drowning. So go, give it a try....

keep calm and code in scala