Programming with null
- // get subdirectories of directory `name`
- def getDirs1(name: String) : List[java.io.File] =
- val dir = new java.io.File(name)
- val xs = dir.listFiles
- if xs == null // dir is not a directory
- then null
- else xs.toList.filter (_.isDirectory)
Programming with optionals
- def getDirs2(name: String) : Option[List[java.io.File]] =
- val dir = new java.io.File(name)
- val xs = dir.listFiles
- if xs == null
- then None
- else Some(xs.toList.filter (_.isDirectory))
Client handling null
- def findTemp : List[java.io.File] =
- var result: List[java.io.File] = null
- var found = false
- for s <- List("/temp", "/tmp") if !found do
- result = getDirs(s)
- found = (result != null)
- end for
- result
- end findTemp
- findTemp match
- case null => println("No Temporary Directory.")
- case result => println(result.length)
Client handling option
- def findTemp2 =
- getDirs2("/temp") orElse getDirs2("/tmp")
- findTemp2
- case None => println("No Temporary Directory.")
- case Some(result) => println(result.length)
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
None (undefined)- def safeDivide (n:Int,m:Int) : Option[Int] =
- if m == 0 then None
- else Some (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)
map, etc.orElse, getOrElse)