diff -r 7ea440e1ffbb -r 8b57dd326a91 progs/lecture2.scala --- a/progs/lecture2.scala Sat Nov 09 22:04:53 2019 +0000 +++ b/progs/lecture2.scala Mon Nov 11 13:24:12 2019 +0000 @@ -1,64 +1,63 @@ // Scala Lecture 2 //================= -// UNFINISHED BUSINESS from Lecture 1 -//==================================== -// for measuring time -def time_needed[T](n: Int, code: => T) = { - val start = System.nanoTime() - for (i <- (0 to n)) code - val end = System.nanoTime() - (end - start) / 1.0e9 -} +// The Option Type +//================= + +// in Java, if something unusually happens, you return null or +// raise an exception +// +//in Scala you use Options instead +// - if the value is present, you use Some(value) +// - if no value is present, you use None -val list = (1 to 1000000).toList -time_needed(10, for (n <- list) yield n + 42) -time_needed(10, for (n <- list.par) yield n + 42) - -// (needs a library and 'magic' option -Yrepl-class-based) - +List(7,2,3,4,5,6).find(_ < 4) +List(5,6,7,8,9).find(_ < 4) -// Just for Fun: Mutable vs Immutable -//==================================== +// better error handling with Options (no exceptions) +// +// Try(something).getOrElse(what_to_do_in_case_of_an_exception) // -// - no vars, no ++i, no += -// - no mutable data-structures (no Arrays, no ListBuffers) + +import scala.util._ +import io.Source + +val my_url = "https://nms.kcl.ac.uk/christian.urban/" + +Source.fromURL(my_url).mkString + +Try(Source.fromURL(my_url).mkString).getOrElse("") + +Try(Some(Source.fromURL(my_url).mkString)).getOrElse(None) -// Q: Count how many elements are in the intersections of -// two sets? +// the same for files +Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None) + +// how to implement a function for reading something from files... -def count_intersection(A: Set[Int], B: Set[Int]) : Int = { - var count = 0 - for (x <- A; if B contains x) count += 1 - count -} +def get_contents(name: String) : List[String] = + Source.fromFile(name).getLines.toList -val A = (1 to 1000).toSet -val B = (1 to 1000 by 4).toSet - -count_intersection(A, B) +get_contents("test.txt") -// but do not try to add .par to the for-loop above - +// slightly better - return Nil +def get_contents(name: String) : List[String] = + Try(Source.fromFile(name).getLines.toList).getOrElse(List()) -//propper parallel version -def count_intersection2(A: Set[Int], B: Set[Int]) : Int = - A.par.count(x => B contains x) +get_contents("text.txt") -count_intersection2(A, B) - +// much better - you record in the type that things can go wrong +def get_contents(name: String) : Option[List[String]] = + Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None) -val A = (1 to 1000000).toSet -val B = (1 to 1000000 by 4).toSet - -time_needed(100, count_intersection(A, B)) -time_needed(100, count_intersection2(A, B)) +get_contents("text.txt") +get_contents("test.txt")