Programming with null
- def find[X](xs: List[X], p: X => Boolean): X = xs match
- case Nil => null.asInstanceOf[X]
- case x :: rest => if p(x) then x else find(rest, p)
- end find
Programming with optionals
- def find[X](xs: List[X], p: X => Boolean): Option[X] = xs match
- case Nil => None
- case x :: rest => if p(x) then Some(x) else find(rest, p)
- end find
x>5, if found return "found x", else find x>3, if found return "found x", else print "not found"- val xs = List(1, 2, 3, 4, 5)
Client handling null
- find(xs, _ > 5) match
- case null => find(xs, _ > 3) match
- case null => "not found"
- case n => s"found $n"
- end match
- case n => s"found $n"
- end match
Client handling option
- find(xs, _ > 5) orElse find(xs, _ > 3) match
- case None => "not found"
- case Some(n) => s"found $n"
- end match
null: no compiler support to check for presence of null-checking, cannot have methodsOptionNone: empty optionNil: empty listnull: reference to nothingUnit is not an option type
Unit always has nothingUnit nothing is ()Nil vs. nullScala
- def sum (xs : List[Int]) : Int = xs match
- case Nil => 0
- case y::ys => y + sum(ys)
Nil: empty listnull: empty referenceJava
- int sum (Node<Integer> xs)
- if (xs == null) return 0;
- else return xs.item + sum(xs.next);
null used to represent emptinessnull does not existKotlin nullable versus non-nullable types
T? in Kotlin resembles Option[T] in Scalanull is used for None? do not allow null- var a: String = "abc"
- a = null /* compilation error */
- a.length /* always safe */
- var b: String? = "abc"
- b = null /* ok */
- b.length /* compiler error */
- b!!.length /* may raise exception */
- /* Safe call */
- b?.length
- /* Explicitly expanded safe call */
- if (b != null) b.length else null
- /* Safe call with default */
- b?.length ?: -1
- /* Explicitly expanded */
- val t = b?.length; if (t != null) t else -1
Safe division returns on zero: None (division undefined)
- def safeDivide (n:Int,m:Int) : Option[Int] =
- if m == 0 then None
- else Some (n/m)
- def safeDivide (n:Int,m:Int) : Option[Int] =
- Option.when(m!=0)(n/m) // Option.unless(m==0)(n/m)
- val i: Option[Int] = Some(4)
- i.map(safeDivide(_,2)) // val res10: Option[Option[Int]] = Some(Some(2))
- val i: Option[Int] = Some(4)
- i.flatMap(safeDivide(_,2)) // val res10: Option[Int] = Some(2)
Option type represents presence/absence of dataEither type represents alternative resultsmap, etc.orElse, getOrElse)