Category: Programming

Desugaring for comprehensions (AKA for expressions)

Recently I stumbled upon a piece of Scala code that might leave you puzzled. Before showing you the code I must spend a few words about the compiler options.

Compiler options

Getting into the glory details of each and every compiler option is out of the scope of this post (see compiler options). Suffice to say you can use some flags to make the Scala compiler stricter and help you find code deficiencies at compile time. The flag I always use, among others, is "-Wunused". So in build.sbt I have:

Read more...

Keep your code clean with algebraic data types (ADTs)

Recently, Daniel Westheide wrote an interesting post about the abuse of the Option type in Scala. You can find it here. I couldn’t agree more with Daniel.

This short story is another example that demonstrates how using Option is not always the best option (pun intended).

I’m developing an advertising service for a customer using Scala. A simplified version of the Ad data structure is the following:

final case class Ad(
    headline: String, 
    description1: String, 
    description2: String
)

At some point they told me we need to support, by adding the headline2 field, two types of ad: standard and expanded. They said: “If headline, description1, and description2 are used, it is a standard ad. If headline, headline2, and description1 are used it is an expanded one. Users won’t include headline2 when the ad is intended to be standard, and won’t include description2 when the ad is intended to be expanded.”

Read more...

Scala: Seq, Map and Set as functions

Yesterday my mate asked me: “I have a List[String] and a Map[String, Int] and I want a List[Int] where its values are those of the Map whose keys match the List[String] elements, maintaining the order. Should I use pattern matching?”. I know, the sentence is a bit convoluted but the code will make it clear, hopefully. Anyway, I replied: “No, you don’t need pattern matching, you just need this”:

 
scala> val m = Map("a" -> 1, "b" -> 2, "c" -> 3)
m: scala.collection.immutable.Map[String,Int] = 
  Map(a -> 1, b -> 2, c -> 3)

scala> val l = List("a", "c", "b")
l: List[String] = List(a, c, b)

scala> l collect m
res0: List[Int] = List(1, 3, 2)

Hold on, how does it work? If you look at the definition of the collect method you’ll see it accepts a PartialFunction, instead I passed a Map to it. Well, it turns out that Map is a PartialFunction.

Read more...

Scala case classes in depth

For this post I’ll consider the following simple case class unless otherwise specified:

case class Person(lastname: String, firstname: String, birthYear: Int)

In this post:

Common knowledge about case classes

When you declare a case class the Scala compiler does the following for you:

Read more...