Hengrui Jiang Hengrui Jiang - 3 months ago 6
Scala Question

What is the advantage of using Option.map over Option.isEmpty and Option.get?

I am a nooby at Scala coming from Java and am currently confused about the best practice considering Options.

I feel like using Option.map is just more functional and beautiful, but this is not a good argument to convince other people. Sometimes, isEmpty check feels more straight forward thus more readable. Is there any objective advantages, or is it just personal preference?

Example:

Variation 1:

someOption.map{ value =>
{
//some lines of code
}
} orElse(foo)


Variation 2:

if(someOption.isEmpty){
foo
} else{
val value = someOption.get
//some lines of code
}


I intentionally excluded the options to use
fold
or pattern matching. I am simply not pleased by the idea of treating
Option
as a collection right now, and using pattern matching for a simple
isEmpty
check is an abuse of pattern matching IMHO. But no matter why I dislike these options, I want to keep the scope of this question to be the above two variations as named in the title.

Answer

using pattern matching for a simple isEmpty check is an abuse of pattern matching IMHO

If you do just want an isEmpty check, isEmpty/isDefined is perfectly fine. But in your case you also want to get the value. And using pattern matching for this is not abuse; it's precisely the basic use-case. Using get allows to very easily make errors like forgetting to check isDefined or making the wrong check:

if(someOption.isEmpty){
  val value = someOption.get
  //some lines of code
} else{
  //some other lines
}

Hopefully testing would catch it, but there's no reason to settle for "hopefully".

Combinators (map and friends) are better than get for the same reason pattern matching is: they don't allow you to make this kind of mistake. Choosing between pattern matching and combinators is a different question. Generally combinators are preferred because they are more composable (as Yuval's answer explains). If you want to do something covered by a single combinator, I'd generally choose them; if you need a combination like map ... getOrElse, or a fold with multi-line branches, it depends on the specific case.