This a continuation of my thirty days of Scala series about learning the programming language Scala. For a list of all posts click here
In my last post I covered the process of setting up my development environment. Now we get down to discussing the actual code.
I worked the Game of Life Kata multiple times, using two different approaches. In the first, I focused on creating an actual Cell class which was responsible for handling it’s own life and death, and responsible for keeping track of it’s neighbors. In the second I created a game class that managed the states of all the cells and tracked the neighbors through a single Set which contained the coordinate pairs of all active cells in the game.
For most of the katas, I was primarily focused on familiarizing myself with the scala syntax. Scala does a number of things differently than C# or Java. Some of this is cosmetic, like how Scala flips the type and parameter names in a method signature, but some of it is more fundamental. In general, Scala seems to be much less prescriptive about syntax for syntax’s sake. The compiler doesn’t care if you forget a semi colon at the end of the line. Single line methods don’t require brackets. You don’t have to explicitly return values from a method, you can just put the value at the end and Scala will assume you wanted it returned. The list goes on and on. It can be very freeing and make it simple to write code without worrying about syntactical details, but for someone coming from a more prescriptive language, it definitely hurts readability. The question is whether I’ll feel the same way after a month of writing and reviewing katas. To a large extent I suspect as my brain gets used to it, the readability will be fine.
However, there are some more fundamental things about Scala that I suspect will not get easier as I get used to it. A good example would be some of the challenges I had with getting my automated testing setup. I decided to use the testing framework specs2, after reviewing some documentation on it. In particular I focused on the acceptance testing syntax documented on their website. The syntax is very impressively clean, consisting of basically a block of plain text with test code interpolated in using a custom string interpolation method. They also have a great syntax for doing repeated tests with different inputs. In general getting a basic test up and running for each of these scenarios was not hard, but when I started to try to do some more complicated setups that weren’t explicitly covered in the documentation I started running into challenges. Debugging these was extremely hard because specs2 makes extremely heavy use of operator overloading to create it’s syntax. Looking at the code, I had a very tough time understanding what it was actually doing, even at a very high level. I had to dig into the code for specs2 on github to even have a basic grasp of even the basic control flow that specs2 very abstract syntax was actually generating.
The issue I was having turned out to be fairly prosaic, it was just an incorrect version number for specs2. I downloaded the right version and everything worked great, but the opaqueness of specs2 operator overloading had me digging into it’s internals unnecessarily because I feared I was misusing something. However, I don’t necessarily disagree with how the specs2 to did things. There’s no arguing that the syntax makes the tests very readable, and get’s rid of a lot of clutter that does nothing to impart meaning. But it does so at the expense of making the testing framework understandable. In this case that’s probably okay, the tradeoff makes sense given how often you’ll be reading your tests, but in Scala the power is definitely there to shoot yourself in the foot by misusing these features.
On the plus side, coming from C# a lot of the functional aspects of Scala felt very familiar. I’m a huge advocate of LINQ and was drawn to functional programming through it before I had even heard the term before. The syntax for Scala’s functional operators for collections are almost exactly identical to LINQ, with some minor differences in terminology (filter vs where, map vs select). I definitely used them fairly heavily, particularly in my second implementation of the kata, where essentially all of the work was various forms of collection manipulation.
In general I found Scala fairly easy to get used to, but I didn’t have any aha moments where I saw why it would be a better fit than C#. Of course this isn’t surprising, given that this was my first foray into it, and that I was doing code kata’s that by their very nature are designed to be fairly language agnostic. I know one major strength of Scala is how effective it’s supposed to be when you’re trying to handle concurrency and parallel processing, so that may be something I start exploring next