I work on a fairly large Java code-base and wanted to start writing Scala for a new project. I’d been asking to write Scala for a while and was finally given the opportunity to do so for a new project. A few parts of the company had started writing Scala code, but my team (which works in a rather siloed module within the code) had not. Our team’s build wasn’t set up for Scala, and no one else on the team knew the language. I took the opportunity and did it in Scala anyway. It was awesome.

The project started off bumpy.

First I had to figure out how to add Scala into our build. This was tough since the project was under time constraints; there wasn’t enough time allotted to fiddle with sbt and ant. So I cheated and stashed all of my code in a completely different section of the code base, and introduced several new dependencies to their project. I’m not proud of it, but it was the most immediate and simple solution. I promised the host project’s owners I would move my code back out and just set up our build when the project was done and I had more time.

Things got better quickly.

Having dumped my tech debt on others to deal with (temporarily, I promise), I finally got to sit down and do some good clean functional programming. It was everything I hoped and dreamed it would be. Not a single null pointer exception the whole damn time. That shit was dank, as they say.

Paralleling code is ridiculously easy in a functional language like Scala. Just a simple

someList.par.map(someFunction)

will map someFunction onto someList in parallel. I took advantage of this powerful abstraction, and it was glorious. I had to write a job that would do a decent amount of work for every user on our site. I added that simple ‘.par’ and ran the job, and quickly discovered that the job was on track to run in ~15 hours instead of the previous ~40 hours, no optimizing on my end whatsoever. I giggled as I thought about how much of a pain in the ass the openMP library was for concurrent programming in C.

My project involved a portion of heavy JSON parsing, which can be written cleanly in Scala. With a little bit of customization of the Jackson library, I ended up with a small amount of code that gave me a highly reusable utility to simply parse JSON into a plain Scala case class. No need for a long chain of null-checking and hard-coded logic for parsing like we’d do in Java. Just give it a type, and have the libraries do the work. The code was so simple I didn’t even have the opportunity to write a buggy implementation by mistake.

No language is without its issues.

Scala definitely has some uglier sides that I learned about. The IDE support is still far less mature than the Java counterparts (on IntelliJ, anyway). Code that’s too wrapped in anonymous functions can’t easily be hit with the debugger, and the debugger is way slower than it is for Java. The refactoring tools are a bit more limited as well; it only supports a subset of the Java capabilities.

I wrote my tests in Java. I thought that my code would probably be needed by other Java code, so testing them in Java could be good. More crucially, laziness kicked in so I didn’t want to use JUnit (the framework used for all our our base test classes) in Scala - that disgusting imperative framework would clog up my immaculate functional code. This ultimately turned out to be a bad idea. The Java to Scala type conversions (converting a Java Map to a Scala Map, for instance) littered my test code and made it difficult to read. Using Scala from Java code is tricky. You need to have those type conversions somewhere, because Java doesn’t have the syntax to cleanly use Scala data types, and it’s not like you’re going to go through the trouble of using a new language just to use Java data structures in your Scala code.

Side note: In my concurrent programming endeavors, I learned the hard way that date formatting in Java is not thread safe. Don’t do it. Save yourself a half-day of frantic and clueless debugging while questioning if the difficulty is because of Scala or just your lack of ability. For once, the problem was neither, it just Java.

More to come

Overall, my functional code is better and more satisfying to write than the Java I’ve been writing. It’s generally more compact, concise, easy to understand, maintainable and testable. Refactors are even easier with the beast of a type system that Scala offers. I had an easier time writing pure functions for which I could write well abstracted tests, and be sleep better at night knowing the code was solid.

I still haven’t deployed this project and haven’t experienced what the maintenance will be like. It will be interesting to see how my code holds up to the scale it will be run at. I’ll write more about that when I get there, stay tuned.