progs/lecture2.scala
changeset 317 607ceabeeffc
parent 316 8b57dd326a91
child 318 029e2862bb4e
--- a/progs/lecture2.scala	Mon Nov 11 13:24:12 2019 +0000
+++ b/progs/lecture2.scala	Mon Nov 11 14:04:22 2019 +0000
@@ -1,6 +1,38 @@
 // Scala Lecture 2
 //=================
 
+// For-Comprehensions Again
+//==========================
+
+// the first produces a result, while the second does not
+for (n <- List(1, 2, 3, 4, 5)) yield n * n
+
+
+for (n <- List(1, 2, 3, 4, 5)) println(n)
+
+
+// String Interpolations
+//=======================
+
+val n = 3
+println("The square of " + n + " is " + square(n) + ".")
+
+println(s"The square of ${n} is ${square(n)}.")
+
+
+// helpful for debugging purposes
+//
+//         "The most effective debugging tool is still careful thought, 
+//          coupled with judiciously placed print statements."
+//                   — Brian W. Kernighan, in Unix for Beginners (1979)
+
+
+def gcd_db(a: Int, b: Int) : Int = {
+  println(s"Function called with ${a} and ${b}.")
+  if (b == 0) a else gcd_db(b, a % b)
+}
+
+gcd_db(48, 18)
 
 
 // The Option Type
@@ -61,46 +93,54 @@
 
 
 
-// For-Comprehensions Again
-//==========================
+// operations on options
 
-// the first produces a result, while the second does not
-for (n <- List(1, 2, 3, 4, 5)) yield n * n
+val lst = List(None, Some(1), Some(2), None, Some(3))
 
-
-for (n <- List(1, 2, 3, 4, 5)) println(n)
+lst.flatten
 
-
-// String Interpolations
-//=======================
+Some(1).get
+None.get
 
-val n = 3
-println("The square of " + n + " is " + square(n) + ".")
-
-println(s"The square of ${n} is ${square(n)}.")
+Some(1).isDefined
+None.isDefined
 
 
-// helpful for debugging purposes
-//
-//         "The most effective debugging tool is still careful thought, 
-//          coupled with judiciously placed print statements."
-//                   — Brian W. Kernighan, in Unix for Beginners (1979)
+val ps = List((3, 0), (3, 2), (4, 2), (2, 0), (1, 0), (1, 1))
+
+// division where possible
+
+for ((x, y) <- ps) yield {
+  if (y == 0) None else Some(x / y)
+}
+
+// getOrElse is for setting a default value
+
+val lst = List(None, Some(1), Some(2), None, Some(3))
+
+for (x <- lst) yield x.getOrElse(0)
+
+
 
 
-def gcd_db(a: Int, b: Int) : Int = {
-  println(s"Function called with ${a} and ${b}.")
-  if (b == 0) a else gcd_db(b, a % b)
-}
-
-gcd_db(48, 18)
+// This may not look any better than working with null in Java, but to
+// see the value, you have to put yourself in the shoes of the
+// consumer of the get_me_an_int function, and imagine you didn't
+// write that function.
+//
+// In Java, if you didn't write this function, you'd have to depend on
+// the Javadoc of the get_me_an_int. If you didn't look at the Javadoc, 
+// you might not know that get_me_an_int could return a null, and your 
+// code could potentially throw a NullPointerException.
 
 
-// Asserts/Testing
-//=================
+
+// even Scala is not immune to problems like this:
 
-assert(gcd(48, 18) == 6)
+List(5,6,7,8,9).indexOf(7)
+List(5,6,7,8,9).indexOf(10)
+List(5,6,7,8,9)(-1)
 
-assert(gcd(48, 18) == 5, "The gcd test failed")
 
 
 
@@ -148,7 +188,6 @@
 def square(x: Int): Int = x * x
 
 
-
 val lst = (1 to 10).toList
 
 lst.map(x => (double(x), square(x)))
@@ -217,6 +256,45 @@
 
 
 
+// if you like verbosity, you can full-specify the literal. 
+// Don't go telling that to people, though
+(1 to 100).filter((x: Int) => x % 2 == 0).sum 
+
+// As x is known to be an Int anyway, you can omit that part
+(1 to 100).filter(x => x % 2 == 0).sum
+
+// As each parameter (only x in this case) is passed only once
+// you can use the wizardy placeholder syntax
+(1 to 100).filter(_ % 2 == 0).sum
+
+// But if you want to re-use your literal, you can also put it in a value
+// In this case, explicit types are required because there's nothing to infer from
+val isEven = (x: Int) => x % 2 == 0
+(1 to 100).filter(isEven).sum
+
+
+
+// Option Type again
+//===================
+
+// a function that turns strings into numbers (similar to .toInt)
+Integer.parseInt("12u34")
+
+
+def get_me_an_int(s: String) : Option[Int] = 
+ Try(Some(Integer.parseInt(s))).getOrElse(None)
+
+val lst = List("12345", "foo", "5432", "bar", "x21", "456")
+for (x <- lst) yield get_me_an_int(x)
+
+// summing up all the numbers
+
+lst.map(get_me_an_int).flatten.sum
+lst.map(get_me_an_int).flatten.sum
+
+lst.flatMap(get_me_an_int).sum
+
+
 
 
 // Map type (upper-case)
@@ -259,103 +337,6 @@
 
 
 
-// Option type (again)
-//=====================
-
-// remember, in Java if something unusually happens, 
-// you return null;
-//
-// in Scala you use Option
-//   - if the value is present, you use Some(value)
-//   - if no value is present, you use None
-
-
-List(7,2,3,4,5,6).find(_ < 4)
-List(5,6,7,8,9).find(_ < 4)
-
-// operations on options
-
-val lst = List(None, Some(1), Some(2), None, Some(3))
-
-lst.flatten
-
-Some(1).get
-None.get
-
-Some(1).isDefined
-None.isDefined
-
-
-None.isDefined
-
-val ps = List((3, 0), (3, 2), (4, 2), (2, 0), (1, 0), (1, 1))
-
-for ((x, y) <- ps) yield {
-  if (y == 0) None else Some(x / y)
-}
-
-// getOrElse is for setting a default value
-
-val lst = List(None, Some(1), Some(2), None, Some(3))
-
-for (x <- lst) yield x.getOrElse(0)
-
-
-
-
-// error handling with Option (no exceptions)
-//
-//  Try(something).getOrElse(what_to_do_in_an_exception)
-//
-import scala.util._
-import io.Source
-
-
-Source.fromURL("""http://www.inf.ucl.ac.uk/staff/urbanc/""").mkString
-
-Try(Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanc/""").mkString).getOrElse("")
-
-Try(Some(Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanc/""").mkString)).getOrElse(None)
-
-
-// a function that turns strings into numbers (similar to .toInt)
-Integer.parseInt("12u34")
-
-
-def get_me_an_int(s: String) : Option[Int] = 
- Try(Some(Integer.parseInt(s))).getOrElse(None)
-
-val lst = List("12345", "foo", "5432", "bar", "x21", "456")
-for (x <- lst) yield get_me_an_int(x)
-
-// summing up all the numbers
-
-lst.map(get_me_an_int).flatten.sum
-lst.map(get_me_an_int).flatten.sum
-
-
-lst.flatMap(get_me_an_int).map(_.toString)
-
-
-// This may not look any better than working with null in Java, but to
-// see the value, you have to put yourself in the shoes of the
-// consumer of the get_me_an_int function, and imagine you didn't
-// write that function.
-//
-// In Java, if you didn't write this function, you'd have to depend on
-// the Javadoc of the get_me_an_int. If you didn't look at the Javadoc, 
-// you might not know that get_me_an_int could return a null, and your 
-// code could potentially throw a NullPointerException.
-
-
-
-// even Scala is not immune to problems like this:
-
-List(5,6,7,8,9).indexOf(7)
-List(5,6,7,8,9).indexOf(10)
-List(5,6,7,8,9)(-1)
-
-
 
 // Pattern Matching
 //==================
@@ -807,18 +788,4 @@
 
 
 
-// if you like verbosity, you can full-specify the literal. 
-// Don't go telling that to people, though
-(1 to 100).filter((x: Int) => x % 2 == 0).sum 
 
-// As x is known to be an Int anyway, you can omit that part
-(1 to 100).filter(x => x % 2 == 0).sum
-
-// As each parameter (only x in this case) is passed only once
-// you can use the wizardy placeholder syntax
-(1 to 100).filter(_ % 2 == 0).sum
-
-// But if you want to re-use your literal, you can also put it in a value
-// In this case, explicit types are required because there's nothing to infer from
-val isEven: (x: Int) => x % 2 == 0
-(1 to 100).filter(isEven).sum