|     51 // some alterative syntax for lists |     51 // some alterative syntax for lists | 
|     52  |     52  | 
|     53 1 :: 2 :: 3 :: Nil |     53 1 :: 2 :: 3 :: Nil | 
|     54 List(1, 2, 3) ::: List(4, 5, 6) |     54 List(1, 2, 3) ::: List(4, 5, 6) | 
|     55  |     55  | 
|         |     56 // also | 
|         |     57 List(1, 2, 3) ++ List(4, 5, 6) | 
|         |     58  | 
|         |     59  | 
|     56 // Equality in Scala is structural |     60 // Equality in Scala is structural | 
|     57 //================================= |     61 //================================= | 
|     58 val a = "Dave" |     62 val a = "Dave" | 
|     59 val b = "Dave" |     63 val b = "Dave" | 
|     60  |     64  | 
|    210 def silly(n: Int) : Int = { |    216 def silly(n: Int) : Int = { | 
|    211   if (n < 10) n * n |    217   if (n < 10) n * n | 
|    212   else n + n |    218   else n + n | 
|    213 } |    219 } | 
|    214  |    220  | 
|    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  |         | 
|    224  |    221  | 
|    225 // If-Conditionals |    222 // If-Conditionals | 
|    226 //================= |    223 //================= | 
|    227  |    224  | 
|    228 // - Scala does not have a then-keyword |    225 // - Scala does not have a then-keyword | 
|    229 // - !both if-else branches need to be present! |    226 // - !both if-else branches need to be present! | 
|    230  |    227  | 
|    231 def fact(n: Int) : Int =  |    228 def fact(n: Int) : Int =  | 
|    232   if (n == 0) 1 else n * fact(n - 1) |    229   if (n == 0) 1 else n * fact(n - 1) | 
|    233  |         | 
|    234  |    230  | 
|    235 fact(5) |    231 fact(5) | 
|    236 fact(150) |    232 fact(150) | 
|    237  |    233  | 
|    238 /* boolean operators |    234 /* boolean operators | 
|    302  |    298  | 
|    303  |    299  | 
|    304 // the same for files |    300 // the same for files | 
|    305 Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None) |    301 Try(Some(Source.fromFile("text.txt").mkString)).getOrElse(None) | 
|    306  |    302  | 
|    307 // function reading something from files... |    303  | 
|         |    304  | 
|         |    305 // how to implement a function for reading something from files... | 
|    308  |    306  | 
|    309 def get_contents(name: String) : List[String] =  |    307 def get_contents(name: String) : List[String] =  | 
|    310   Source.fromFile(name).getLines.toList |    308   Source.fromFile(name).getLines.toList | 
|    311  |    309  | 
|    312 get_contents("test.txt") |    310 get_contents("test.txt") | 
|    401 for ((m, n) <- lst) yield m + n  |    399 for ((m, n) <- lst) yield m + n  | 
|    402  |    400  | 
|    403 for (p <- lst) yield p._1 + p._2  |    401 for (p <- lst) yield p._1 + p._2  | 
|    404  |    402  | 
|    405  |    403  | 
|    406 // general pattern of for-yield |    404 // general pattern of for-yield  | 
|         |    405 // (yield can be several lines) | 
|    407  |    406  | 
|    408 for (p <- ...) yield { |    407 for (p <- ...) yield { | 
|    409   // potentially complicated |    408   // potentially complicated | 
|    410   // calculation of a result |    409   // calculation of a result | 
|    411 } |    410 } | 
|    441  |    440  | 
|    442  |    441  | 
|    443 // BTW: a roundabout way of printing out a list, say |    442 // BTW: a roundabout way of printing out a list, say | 
|    444 val lst = ('a' to 'm').toList |    443 val lst = ('a' to 'm').toList | 
|    445  |    444  | 
|    446 for (n <- lst) println(n) |         | 
|    447  |         | 
|    448 for (i <- (0 until lst.length)) println(lst(i)) |    445 for (i <- (0 until lst.length)) println(lst(i)) | 
|         |    446  | 
|    449  |    447  | 
|    450 // Why not just? Why making your life so complicated? |    448 // Why not just? Why making your life so complicated? | 
|    451 for (c <- lst) println(c) |    449 for (c <- lst) println(c) | 
|    452  |    450  | 
|    453 // Aside: concurrency  |    451 // Aside: concurrency  | 
|    454 // (scala <<..parallel_collections...>> -Yrepl-class-based) |    452 // scala -Yrepl-class-based -cp scala-parallel-collections_2.13-0.2.0.jar  | 
|         |    453  | 
|    455 for (n <- (1 to 10)) println(n) |    454 for (n <- (1 to 10)) println(n) | 
|    456  |    455  | 
|    457 import scala.collection.parallel.CollectionConverters._ |    456 import scala.collection.parallel.CollectionConverters._ | 
|    458  |    457  | 
|    459 for (n <- (1 to 10).par) println(n) |    458 for (n <- (1 to 10).par) println(n) | 
|    465   for (i <- (0 to n)) code |    464   for (i <- (0 to n)) code | 
|    466   val end = System.nanoTime() |    465   val end = System.nanoTime() | 
|    467   (end - start) / 1.0e9 |    466   (end - start) / 1.0e9 | 
|    468 } |    467 } | 
|    469  |    468  | 
|    470  |         | 
|    471 val list = (1 to 1000000).toList |    469 val list = (1 to 1000000).toList | 
|    472 time_needed(10, for (n <- list) yield n + 42) |    470 time_needed(10, for (n <- list) yield n + 42) | 
|    473 time_needed(10, for (n <- list.par) yield n + 42) |    471 time_needed(10, for (n <- list.par) yield n + 42) | 
|    474  |    472  | 
|    475 val list = (1 to 1000000).toList.map(BigInt(_)) |    473 // ...but par does not make everything faster | 
|         |    474  | 
|    476 list.sum |    475 list.sum | 
|    477 list.par.sum |    476 list.par.sum | 
|    478 list.par.reduce(_ + _) |         | 
|    479 list.par.aggregate(BigInt(0))(_ + _, _ + _) |         | 
|    480  |    477  | 
|    481 time_needed(10, list.sum) |    478 time_needed(10, list.sum) | 
|    482 time_needed(10, list.par.sum) |    479 time_needed(10, list.par.sum) | 
|    483 time_needed(10, list.par.reduce(_ + _)) |    480  | 
|    484 time_needed(10, list.par.aggregate(BigInt(0))(_ + _, _ + _)) |    481  | 
|    485  |    482 // Mutable vs Immutable | 
|    486  |    483 //====================== | 
|    487 // Just for "Fun": Mutable vs Immutable |    484 // | 
|    488 //======================================= |    485 // Remember: | 
|    489 // |         | 
|    490 // - no vars, no ++i, no += |    486 // - no vars, no ++i, no += | 
|    491 // - no mutable data-structures (no Arrays, no ListBuffers) |    487 // - no mutable data-structures (no Arrays, no ListBuffers) | 
|    492  |    488  | 
|    493  |    489 // But what the heck.... | 
|    494 // Q: Count how many elements are in the intersections of two sets? |    490 // Q: Count how many elements are in the intersections of two sets? | 
|    495 // A; IMPROPER WAY (mutable counter) |    491 // A; IMPROPER WAY (mutable counter) | 
|    496  |    492  | 
|    497 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { |    493 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { | 
|    498   var count = 0 |    494   var count = 0 | 
|    499   for (x <- A; if (B contains x)) count += 1  |    495   for (x <- A.par; if (B contains x)) count += 1  | 
|    500   count |    496   count | 
|    501 } |    497 } | 
|    502  |    498  | 
|    503 val A = (1 to 1000).toSet |    499 val A = (0 to 999).toSet | 
|    504 val B = (1 to 1000 by 4).toSet |    500 val B = (0 to 999 by 4).toSet | 
|    505  |    501  | 
|    506 count_intersection(A, B) |    502 count_intersection(A, B) | 
|    507  |    503  | 
|    508 // but do not try to add .par to the for-loop above |    504 // but do not try to add .par to the for-loop above | 
|    509  |    505  | 
|    513   A.par.count(x => B contains x) |    509   A.par.count(x => B contains x) | 
|    514  |    510  | 
|    515 count_intersection2(A, B) |    511 count_intersection2(A, B) | 
|    516  |    512  | 
|    517  |    513  | 
|    518 //another example |    514 //another bad example | 
|    519 def test() = { |    515 def test() = { | 
|    520   var cnt = 0 |    516   var cnt = 0 | 
|    521   for(i <- (1 to 1000000).par) cnt += 1 |    517   for(i <- (1 to 1000000).par) cnt += 1 | 
|    522   println(cnt) |    518   println(cnt) | 
|    523 } |    519 } | 
|    524  |    520  | 
|    525 test() |    521 test() | 
|    526  |    522  | 
|    527 //for measuring time |         | 
|    528 def time_needed[T](n: Int, code: => T) = { |         | 
|    529   val start = System.nanoTime() |         | 
|    530   for (i <- (0 to n)) code |         | 
|    531   val end = System.nanoTime() |         | 
|    532   (end - start) / 1.0e9 |         | 
|    533 } |         | 
|    534  |         | 
|    535 val A = (1 to 1000000).toSet |         | 
|    536 val B = (1 to 1000000 by 4).toSet |         | 
|    537  |         | 
|    538 time_needed(10, count_intersection(A, B)) |         | 
|    539 time_needed(10, count_intersection2(A, B)) |         | 
|    540  |         | 
|    541  |    523  | 
|    542 // Further Information |    524 // Further Information | 
|    543 //===================== |    525 //===================== | 
|    544  |    526  | 
|    545 // The Scala homepage and general information is at |    527 // The Scala homepage and general information is at |