35 // Collections  | 
    35 // Collections  | 
    36 //=============  | 
    36 //=============  | 
    37 List(1,2,3,1)  | 
    37 List(1,2,3,1)  | 
    38 Set(1,2,3,1)  | 
    38 Set(1,2,3,1)  | 
    39   | 
    39   | 
         | 
    40 // ranges  | 
    40 1 to 10  | 
    41 1 to 10  | 
    41 (1 to 10).toList  | 
    42 (1 to 10).toList  | 
    42   | 
    43   | 
    43 (1 until 10).toList  | 
    44 (1 until 10).toList  | 
    44   | 
    45   | 
    45 // an element in a list  | 
    46 // picking an element in a list  | 
    46 val lst = List(1, 2, 3, 1)  | 
    47 val lst = List(1, 2, 3, 1)  | 
    47 lst(0)  | 
    48 lst(0)  | 
    48 lst(2)  | 
    49 lst(2)  | 
    49   | 
    50   | 
    50 // some alterative syntax for lists  | 
    51 // some alterative syntax for lists  | 
    51   | 
    52   | 
    52 1 :: 2 :: 3 :: Nil  | 
    53 1 :: 2 :: 3 :: Nil  | 
    53 List(1, 2, 3) ::: List(4, 5, 6)  | 
    54 List(1, 2, 3) ::: List(4, 5, 6)  | 
    54   | 
    55   | 
    55 // Equality is structural  | 
    56 // Equality in Scala is structural  | 
    56 //========================  | 
    57 //=================================  | 
    57 val a = "Dave"  | 
    58 val a = "Dave"  | 
    58 val b = "Dave"  | 
    59 val b = "Dave"  | 
    59   | 
    60   | 
    60 if (a == b) println("Equal") else println("Unequal") | 
    61 if (a == b) println("Equal") else println("Unequal") | 
    61   | 
    62   | 
    74 // Printing/Strings  | 
    75 // Printing/Strings  | 
    75 //==================  | 
    76 //==================  | 
    76   | 
    77   | 
    77 println("test") | 
    78 println("test") | 
    78   | 
    79   | 
    79 val tst = "This is a " + "test\n"   | 
    80 val tst = "This is a " ++ "test"   | 
         | 
    81 print(tst)  | 
    80 println(tst)  | 
    82 println(tst)  | 
    81   | 
    83   | 
    82 val lst = List(1,2,3,1)  | 
    84 val lst = List(1,2,3,1)  | 
    83   | 
    85   | 
    84   | 
    86   | 
    85 println(lst.toString)  | 
    87 println(lst.toString)  | 
         | 
    88   | 
         | 
    89 println(lst.mkString)  | 
    86 println(lst.mkString(",")) | 
    90 println(lst.mkString(",")) | 
    87   | 
    91   | 
    88 println(lst.mkString(", ")) | 
    92 println(lst.mkString(", ")) | 
    89   | 
    93   | 
    90 // some methods take more than one argument  | 
    94 // some methods take more than one argument  | 
    91 println(lst.mkString("{", ",", "}")) | 
    95 println(lst.mkString("{", ",", "}")) | 
    92   | 
    96   | 
         | 
    97 // (in this case .mkString can take no, one,   | 
         | 
    98 // or three arguments...this has to do with  | 
         | 
    99 // default arguments)  | 
    93   | 
   100   | 
    94   | 
   101   | 
    95 // Conversion methods  | 
   102 // Conversion methods  | 
    96 //====================  | 
   103 //====================  | 
    97   | 
   104   | 
    98 List(1,2,3,1).toString  | 
   105 List(1,2,3,1).toString  | 
    99 List(1,2,3,1).toSet  | 
   106 List(1,2,3,1).toSet  | 
         | 
   107   | 
   100 "hello".toList.tail  | 
   108 "hello".toList.tail  | 
   101 1.toDouble  | 
   109 1.toDouble  | 
   102   | 
   110   | 
   103   | 
   111   | 
   104 // useful list methods  | 
   112 // useful list methods  | 
   117 "1,2,3,4,5".split(",3,").mkString("\n") | 
   125 "1,2,3,4,5".split(",3,").mkString("\n") | 
   118   | 
   126   | 
   119 "abcdefg".startsWith("abc") | 
   127 "abcdefg".startsWith("abc") | 
   120   | 
   128   | 
   121   | 
   129   | 
   122 // Types (slide)  | 
   130 // Types (see slide)  | 
   123 //===============  | 
   131 //===================  | 
   124   | 
   132   | 
   125 /* Scala is a strongly typed language  | 
   133 /* Scala is a strongly typed language  | 
   126    | 
   134    | 
   127  * some base types  | 
   135  * base types  | 
   128   | 
   136   | 
   129     Int, Long, BigInt, Float, Double  | 
   137     Int, Long, BigInt, Float, Double  | 
   130     String, Char  | 
   138     String, Char  | 
   131     Boolean  | 
   139     Boolean...  | 
   132   | 
   140   | 
   133  * some compound types   | 
   141  * compound types   | 
   134   | 
   142   | 
   135     List[Int],  | 
   143     List[Int]  | 
   136     Set[Double]  | 
   144     Set[Double]  | 
   137     Pairs: (Int, String)          | 
   145     Pairs: (Int, String)          | 
   138     List[(BigInt, String)]  | 
   146     List[(BigInt, String)]  | 
   139     Option[Int]  | 
   147     Option[Int]  | 
         | 
   148   | 
         | 
   149  * user-defined types (later)  | 
         | 
   150   | 
   140 */  | 
   151 */  | 
   141   | 
   152   | 
   142   | 
   153   | 
         | 
   154 // you can make the type of a value explicit  | 
   143 val name: String = "leo"  | 
   155 val name: String = "leo"  | 
   144   | 
   156   | 
   145   | 
   157   | 
   146 // type errors  | 
   158 // type errors  | 
   147 math.sqrt("64") | 
   159 math.sqrt("64") | 
   172 def incr(x: Int) : Int = x + 1  | 
   185 def incr(x: Int) : Int = x + 1  | 
   173 def double(x: Int) : Int = x + x  | 
   186 def double(x: Int) : Int = x + x  | 
   174 def square(x: Int) : Int = x * x  | 
   187 def square(x: Int) : Int = x * x  | 
   175   | 
   188   | 
   176 def str(x: Int) : String = x.toString  | 
   189 def str(x: Int) : String = x.toString  | 
         | 
   190   | 
         | 
   191 incr(3)  | 
         | 
   192 double(4)  | 
   177 square(6)  | 
   193 square(6)  | 
         | 
   194 str(3)  | 
   178   | 
   195   | 
   179   | 
   196   | 
   180 // The general scheme for a function: you have to give a type   | 
   197 // The general scheme for a function: you have to give a type   | 
   181 // to each argument and a return type of the function  | 
   198 // to each argument and a return type of the function  | 
   182 //  | 
   199 //  | 
   193 def silly(n: Int) : Int = { | 
   210 def silly(n: Int) : Int = { | 
   194   if (n < 10) n * n  | 
   211   if (n < 10) n * n  | 
   195   else n + n  | 
   212   else n + n  | 
   196 }  | 
   213 }  | 
   197   | 
   214   | 
         | 
   215 def another_silly(x: Int, y: String) : String = { | 
         | 
   216   if (x <= 12) y  | 
         | 
   217   else x.toString  | 
         | 
   218 }  | 
         | 
   219   | 
         | 
   220 another_silly(2, "two")  | 
         | 
   221 another_silly(12, "twelf")  | 
         | 
   222 another_silly(20, "twenty")  | 
         | 
   223   | 
   198   | 
   224   | 
   199 // If-Conditionals  | 
   225 // If-Conditionals  | 
   200 //=================  | 
   226 //=================  | 
   201   | 
   227   | 
   202 // - Scala does not have a then-keyword  | 
   228 // - Scala does not have a then-keyword  | 
   203 // - both if-else branches need to be present  | 
   229 // - !both if-else branches need to be present!  | 
   204   | 
   230   | 
   205 def fact(n: Int) : Int =   | 
   231 def fact(n: Int) : Int =   | 
   206   if (n == 0) 1 else n * fact(n - 1)  | 
   232   if (n == 0) 1 else n * fact(n - 1)  | 
   207   | 
   233   | 
   208   | 
   234   | 
   248   | 
   274   | 
   249   | 
   275   | 
   250 // Option type  | 
   276 // Option type  | 
   251 //=============  | 
   277 //=============  | 
   252   | 
   278   | 
   253 //in Java if something unusually happens, you return null  | 
   279 //in Java if something unusually happens, you return null or something  | 
   254 //  | 
   280 //  | 
   255 //in Scala you use Options instead  | 
   281 //in Scala you use Options instead  | 
   256 //   - if the value is present, you use Some(value)  | 
   282 //   - if the value is present, you use Some(value)  | 
   257 //   - if no value is present, you use None  | 
   283 //   - if no value is present, you use None  | 
   258   | 
   284   | 
   297 // much better - you record in the type that things can go wrong   | 
   323 // much better - you record in the type that things can go wrong   | 
   298 def get_contents(name: String) : Option[List[String]] =   | 
   324 def get_contents(name: String) : Option[List[String]] =   | 
   299   Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None)  | 
   325   Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None)  | 
   300   | 
   326   | 
   301 get_contents("text.txt") | 
   327 get_contents("text.txt") | 
   302   | 
   328 get_contents("test.txt") | 
   303   | 
   329   | 
   304   | 
   330   | 
   305 // String Interpolations  | 
   331 // String Interpolations  | 
   306 //=======================  | 
   332 //=======================  | 
   307   | 
   333   | 
   344   | 
   370   | 
   345 for (n <- (1 to 10).toList;   | 
   371 for (n <- (1 to 10).toList;   | 
   346      m <- (1 to 10).toList) yield m * n  | 
   372      m <- (1 to 10).toList) yield m * n  | 
   347   | 
   373   | 
   348   | 
   374   | 
         | 
   375 // you can assign the result of a for-comprehension  | 
         | 
   376 // to a value  | 
   349 val mult_table =   | 
   377 val mult_table =   | 
   350   for (n <- (1 to 10).toList;   | 
   378   for (n <- (1 to 10).toList;   | 
   351        m <- (1 to 10).toList) yield m * n  | 
   379        m <- (1 to 10).toList) yield m * n  | 
   352   | 
   380   | 
   353 println(mult_table.mkString)  | 
   381 println(mult_table.mkString)  | 
   424   | 
   452   | 
   425 // Why not just? Why making your life so complicated?  | 
   453 // Why not just? Why making your life so complicated?  | 
   426 for (c <- lst) println(c)  | 
   454 for (c <- lst) println(c)  | 
   427   | 
   455   | 
   428 // Aside: concurrency   | 
   456 // Aside: concurrency   | 
   429 // (ONLY WORKS OUT-OF-THE-BOX IN SCALA 2.11.8, not in SCALA 2.12)  | 
   457 // (scala <<..parallel_collections...>> -Yrepl-class-based)  | 
   430 // (would need to have this wrapped into a function, or  | 
         | 
   431 //  REPL called with scala -Yrepl-class-based)  | 
         | 
   432 for (n <- (1 to 10)) println(n)  | 
   458 for (n <- (1 to 10)) println(n)  | 
         | 
   459   | 
         | 
   460 import scala.collection.parallel.CollectionConverters._  | 
         | 
   461   | 
   433 for (n <- (1 to 10).par) println(n)  | 
   462 for (n <- (1 to 10).par) println(n)  | 
   434   | 
   463   | 
   435   | 
   464   | 
   436 // for measuring time  | 
   465 // for measuring time  | 
   437 def time_needed[T](n: Int, code: => T) = { | 
   466 def time_needed[T](n: Int, code: => T) = { | 
   454 // - no vars, no ++i, no +=  | 
   483 // - no vars, no ++i, no +=  | 
   455 // - no mutable data-structures (no Arrays, no ListBuffers)  | 
   484 // - no mutable data-structures (no Arrays, no ListBuffers)  | 
   456   | 
   485   | 
   457   | 
   486   | 
   458 // Q: Count how many elements are in the intersections of two sets?  | 
   487 // Q: Count how many elements are in the intersections of two sets?  | 
         | 
   488 // A; IMPROPER WAY (mutable counter)  | 
   459   | 
   489   | 
   460 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { | 
   490 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { | 
   461   var count = 0  | 
   491   var count = 0  | 
   462   for (x <- A; if (B contains x)) count += 1   | 
   492   for (x <- A; if (B contains x)) count += 1   | 
   463   count  | 
   493   count  |