Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Option

Tags:

scala

I learn Scala for some time and can't clearly understand the usage of Option. It helps me to avoid null checks when I chain functions (according to docs). That's clear for me :)

Next I see that Option can be kind of indicator for developer that null value is possible here and it must be handled. Is it true? If yes should I use Option whereever it's possible? For example

class Racer {
    val car = new Car()
}

I have Racer class and I'm sure that car field can't be null (because it's constant and get a value when I create Racer instance). No need for Option here.

class Racer {
    var car = new Car()
}

Here I make it so that the car can change. And it's possible for someone to assign null to car. Should I use Option here? If yes I notice that all my class fields are candidates for Option. And my code looks like this

class Racer {
    var car: Option[Car] = None
    var currentRace: Option[Race] = None
    var team: Option[Team] = None
    ...
}

Does it look good? For me it seems kind of Option overusing.

def foo(): Result = {
    if( something )
        new Result()
    else
        null
}

I have a method which can return null. Should I return Option instead? Should I always do it if it's possible for method to return null?

Any thoughts about it would be helpful. Thanks in advance!

My question is similiar to Why option but I think it's not the same. It's more about when, not why. :)

like image 895
Soteric Avatar asked Mar 14 '12 08:03

Soteric


People also ask

When should you use a put option?

Put options are in the money when the stock price is below the strike price at expiration. The put owner may exercise the option, selling the stock at the strike price. Or the owner can sell the put option to another buyer prior to expiration at fair market value.

What do you mean by option?

Definition of option (Entry 1 of 2) 1 : an act of choosing hard to make an option between such alternatives. 2a : the power or right to choose : freedom of choice He has the option to cancel the deal. b : a privilege of demanding fulfillment of a contract on any day within a specified time.

What is the rule of option?

As per theory, buying option has a limited liability where a trader's loss is restricted to the premium paid while selling option has unlimited liability. But due to the new rules, even a buyer of option has to bear unlimited liability in case she could not square off positions before expiry and option becomes an ITM.


3 Answers

You should avoid null as much as possible in Scala. It really only exists for interoperability with Java. So, instead of null, use Option whenever it's possible that a function or method can return "no value", or when it's logically valid for a member variable to have "no value".

With regard to your Racer example: Is a Racer really valid if it doesn't have a car, currentRace and team? If not, then you shouldn't make those member variables options. Don't just make them options because it's theoretically possible to assign them to null; do it only if logically you consider it a valid Racer object if any of those member variables has no value.

In other words, it's best to pretend as if null doesn't exist. The use of null in Scala code is a code smell.

def foo(): Option[Result] = if (something) Some(new Result()) else None

Note that Option has many useful methods to work with.

val opt = foo()

// You can use pattern matching
opt match {
  case Some(result) => println("The result is: " + result)
  case None         => println("There was no result!")
}

// Or use for example foreach
opt foreach { result => println("The result is: " + result) }

Also, if you want to program in the functional style, you should avoid mutable data as much as possible, which means: avoid the use of var, use val instead, use immutable collections and make your own classes immutable as much as possible.

like image 76
Jesper Avatar answered Oct 05 '22 20:10

Jesper


When it comes to functional programming in Scala, Option is much preferable than null since it is type-safe and plays nice with other constructs in the functional paradigm.

Especially, you can easily write idiomatic code using high-order functions on Option. This Scala Option Cheat Sheet is a helpful read on the topic.

like image 26
pad Avatar answered Oct 05 '22 20:10

pad


While Option can makes your class definition look verbose, the alternative is to not know when you need to test whether a variable is defined. I think that in your example, if your class were immutable (all the fields were vals), you would not need so many Options.

For your method foo, if you return null, you need to document it and the client needs to read that documentation. Then the client will write a bunch of code like:

val result = foo(x)
if (result != null) {
  println(result)
}

If instead you define foo to return an Option[Result], the type system forces the client to handle the possibility of an undefined result. They also have the full power of the collections classes.

result foreach println

An additional advantage of using the collections method with an Option instead of testing for null is that if your method is extended to a multi-element collection (such as a List), you might not need to change your code at all. For example, you might initially assume your Racer can only have a single crew, so you define val crew: Option[Crew] and you might test if the crew is older than 30 with crew.forall(_.age > 30).getOrElse(false). Now if you changed the definition to val crew: List[Crew] your old code would still compile and now you would check if all of your crew members are over 30.

Sometimes you need to deal with null because libraries you are using may return it. For example, when you get a resource, you might get a null result. Fortunately, it is easy to defensively wrap results so they are transformed into an option.

val resource = Option(this.getClass.getResource("foo"))

If getResource returned null then resource equals None, and otherwise it is a Some[URL]. Cool!

Unfortunately, Option is likely to have some overhead because it involves an extra object creation. However, that overhead is minimal compared to a null pointer exception!

like image 29
schmmd Avatar answered Oct 05 '22 20:10

schmmd