Null-coalescing(??) in scala


I was doing my homework today(yes I am aware I should be enjoying myself on 30th December) and had some problems with concatenating possibly null strings in LINQ. Quick trip to StackOverflow and I find out C# has some funky operators that solve this in a (sort-of) clean way.

1
var outputString = input1 ?? "" + input2 ?? "";

I like type inference so I use var’s extensively - please don’t judge me. What this does is concatenate input1 and input2 substituting null values with empty string. In scala you would write something like

1
val outputString = Option(input1).getOrElse("") + Option(input2).getOrElse("")

but that’s verbose and ugly. Wrapping and unwrapping to get some added semantics of the Option factory(returns None for null). But you shouldn’t have nulls in the first place if you’re using scala. That’s what Option is for! Enough ranting, let’s implement this ?? operator in scala.

1
2
3
implicit class NullCoalescent[A](a: A){
  def ??(b: => A) = if(a!=null) a else b
}

Yup. That’s it! You only need this in scope and of you go writing code C#-style.

1
2
3
4
5
scala> "hi" ?? "there"
res0: String = hi

scala> (null:String) ?? "empty"
res2: String = empty

Note the type of b parameter in ?? method. It’s => A. By name evaluation. This means our new operator behaves properly and only evaluates right hand side if value is in fact null. This lets you for example log unexpected nulls while substituting for default value

1
2
3
4
val key = valueFromUser ?? {
  log("key is null!"}
  defaultKey
}

This works because scala let’s you do side effects like that. I just wanted to add one reason why I love scala is this easy way of defining structures that feel like they’re part of the language while being nothing more than just libraries.


Last modified on 2013-01-27

Previous Union types in scala
Next Monadic IO with ScalaZ