Ever thought about learning a new language (since this is a tech article, I’m referring to programming languages)? Then go “Well, I know X, so it won’t be that difficult to learn Y” – and I agree. As a software engineer, learning a language is not hard. However, diving straight in might lead to disappointment, self-reflection and thoughts about changing profession.

I had all this in mind when I decided to jump the Java ship and board the Scala one. The Java world is nice. It’s…

  • imperative (my favourite tech word since I found out what it means),
  • object oriented (with a few functional touches that Java veterans detest and functional programmers think of as a joke), and
  • quite mature, with:
    • lots of support,
    • lots of stackoverflow-answered questions, and above all,
    • a decent documentation (that I thought the first time I was looking for hours how to convert a list to a map in Scala and all seemed gibberish to me).

My Java skills are quite strong (heck, I know what a volatile variable is) and when you are in a comfort zone, it’s difficult to get out. Nevertheless, Rentalcars.com has an experimentation culture so I theorised that I could learn Scala in a month; let’s experiment with me as a guinea pig and see if I’m right (I’m not sure that’s what we have in mind when we say experimentation culture). I’ve even joined an amazing team which works with the latest tech involving Scala, Akka, Spark and lots of AWS services.

Before joining the team, I visited the Scala ship so I’d know my way around once it set sail. I read a few introductory sections of a couple of books, tried to solve some algorithmic problems, followed a course by Martin Odersky and started a few toy projects to see how dependency management works. I started to feel comfortable with functional programming. I even used Currying successfully at least once without looking at a book. But time was up, as the ship was setting sail.

When I joined the team I opened one project, then another, then another. I got nothing. The fact that Spark and Akka were involved kind of blurred the waters. Fortunately, my team is composed of some amazing engineers. I got help in understanding basic concepts and Scala patterns which I’ll enumerate here. Bear in mind that this is not an article for learning Scala and it doesn’t aim to be accurate. Think of it as a number of hints, like when you ask a stranger to give you navigation guidelines; you know it’s close but those instructions weren’t clear because the second turn on the right was in fact the third (small streets don't count, especially if they are parking entrances).

Alas, that was a long intro… hope you’re still reading.

Case classes

How do you create an immutable object in Java? Then you have to write a hashCode, an equals and a toString method.? Oh, and make it Serializable: it should be immutable since you may cache it or deserialisze it as part of an API. Well, a case class can do all these things for you. What Lombok gives you, Scala gives you more of. A case class provides all these capabilities and also gives you a companion object (a what?) for free.

Companion objects

A companion object can be used to support various patterns. Its most basic usage is to provide smart constructors (in Java, we usually see some static valueOf methods). For instance:

case class Dog(name: String, barkLevel: Int, goodBoy: Boolean)

…will auto-generate the following object:

object Dog {
    def apply(name: String, barkLevel: Int, goodBoy: Boolean): Dog = 
    new Dog(name, barkLevel, goodBoy)
}

So when you instantiate a dog you use neither new nor apply. Apply is implied when you don’t provide a function name. You can just call:

Dog(“MoonMoon”, 2, true)

Another use of a companion object would be to define a set of implicits that will accompany the class instances . (I beg your pardon?)

Implicits
An implicit is a definition of something that stays in the scope in which it was defined. Think it as dependency injection. At the beginning, it’s good to think of it as Autowire in Spring (you don’t know what that is? I’m so jealous).

For instance, let’s think of our Dog. It has a goodBoy property, but for some people, good boy dogs are dogs that don’t bark – and for others, they’re dogs that do bark (mainly at strangers) because they guard something. So let’s remove the good boy and instead tell people to provide us with an implicit evaluator of a good boy. Our function will look like:

def isGoodBoy(dog: Dog)(implicit evaluator: GoodboyEvaluator) = evaluator.evaluate(dog)

The compiler will tell you that there is no GoodboyEvaluator in scope because none was instantiated and marked as implicit (yes, this "dependency injection" happens on compile time). Providing it in the Dog companion object will make it work.

object Dog {
    def apply(name: String, barkLevel: Int): Dog = new Dog(name, barkLevel)
    implicit val evaluator: GoodboyEvaluator = new GoodboyEvaluator() { 
        def evaluate(dog: Dog): Boolean = return dog.barkLevel < 5
    }
}

The use of these implicit definitions is typically noticeable in the type class pattern. This pattern is commonly used in Json libraries like circe (https://circe.github.io/circe/).

Pattern matching

Don’t you hate doing instanceof and casting in Java? In Scala, you can do pattern matching. I was confused the first time I heard it; this is not about Regexes. Here’s an example:

def castToDog(a: Any): Option[Dog] = a match { 
    case dog: Dog => Some(dog)
    case _ => None
}

The For

One of my favourite first things I’ve learned is the For. Forget about for-loops: this For is for better workflow management separating error management from the main workflow. I’d recommend you watch this video: https://www.youtube.com/watch?v=WDaw2yXAa50

Final hint

And my final hint to you is how to manage Either. Hell, did I spent a lot of hours trying to find out how to do a flatMap or a map on an Either (with Scala 2.11.x).
Do this:

import cats.syntax.either._

Bear in mind that this syntax enrichment is a standard in Scala. If you are looking at an answer on stackoverflow and you are like "But this doesn’t compile", there is a magic import that the author left out (I still don’t know why they do this… it’s torture).

To close this off, I’m really enjoying Scala and I even wave happily to the Java ship from afar. My aim is to learn at least one new thing every day about Scala and the technologies that surround it . Also, I try to contribute to open- source projects: even if my pull requests get rejected or re-written, I still learn something new.