|    238  |    255  | 
|    239  |    256  | 
|    240 // the same for files |    257 // the same for files | 
|    241 Source.fromFile("test.txt").mkString |    258 Source.fromFile("test.txt").mkString | 
|    242  |    259  | 
|         |    260 // function reading something from files... | 
|         |    261  | 
|         |    262 def get_contents(name: String) : List[String] =  | 
|         |    263   Source.fromFile(name).getLines.toList | 
|         |    264  | 
|         |    265 get_contents("test.txt") | 
|         |    266  | 
|         |    267 // slightly better - return Nil | 
|         |    268 def get_contents(name: String) : List[String] =  | 
|         |    269   Try(Source.fromFile(name).getLines.toList).getOrElse(Nil) | 
|         |    270  | 
|         |    271 get_contents("text.txt") | 
|         |    272  | 
|         |    273 // much better - you record in the type that things can go wrong  | 
|         |    274 def get_contents(name: String) : Option[List[String]] =  | 
|         |    275   Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None) | 
|         |    276  | 
|         |    277 get_contents("text.txt") | 
|         |    278  | 
|         |    279  | 
|    243  |    280  | 
|    244 // String Interpolations |    281 // String Interpolations | 
|    245 //======================= |    282 //======================= | 
|    246  |    283  | 
|    247 val n = 3 |    284 val n = 3 | 
|    248 println("The square of " + n + " is " + square(n) + ".") |    285 println("The square of " + n + " is " + square(n) + ".") | 
|    249  |    286  | 
|    250 println(s"The square of ${n} is ${square(n)}.") |    287 println(s"The square of ${n} is ${square(n)}.") | 
|    251  |    288  | 
|         |    289  | 
|         |    290 // helpful for debugging purposes | 
|         |    291 // | 
|         |    292 //         "The most effective debugging tool is still careful thought,  | 
|         |    293 //          coupled with judiciously placed print statements." | 
|         |    294 //                   — Brian W. Kernighan, in Unix for Beginners (1979) | 
|    252  |    295  | 
|    253  |    296  | 
|    254 def gcd_db(a: Int, b: Int) : Int = { |    297 def gcd_db(a: Int, b: Int) : Int = { | 
|    255   println(s"Function called with ${a} and ${b}.") |    298   println(s"Function called with ${a} and ${b}.") | 
|    256   if (b == 0) a else gcd_db(b, a % b) |    299   if (b == 0) a else gcd_db(b, a % b) | 
|    280   for (n <- (1 to 10).toList;  |    323   for (n <- (1 to 10).toList;  | 
|    281        m <- (1 to 10).toList) yield m * n |    324        m <- (1 to 10).toList) yield m * n | 
|    282  |    325  | 
|    283 mult_table.sliding(10,10).mkString("\n") |    326 mult_table.sliding(10,10).mkString("\n") | 
|    284  |    327  | 
|    285 // the list can also be constructed in any other way |    328 // the list/set/... can also be constructed in any  | 
|         |    329 // other way | 
|    286 for (n <- List(10,12,4,5,7,8,10)) yield n * n |    330 for (n <- List(10,12,4,5,7,8,10)) yield n * n | 
|    287  |    331  | 
|    288  |    332  | 
|    289 // with if-predicates |    333 // with if-predicates / filters | 
|    290  |    334  | 
|    291 for (n <- (1 to 3).toList;  |    335 for (n <- (1 to 3).toList;  | 
|    292      m <- (1 to 3).toList; |    336      m <- (1 to 3).toList; | 
|    293      if (n + m) % 2 == 0) yield (n, m) |    337      if (n + m) % 2 == 0) yield (n, m) | 
|    294  |    338  | 
|    303 for ((m, n) <- lst) yield m + n  |    347 for ((m, n) <- lst) yield m + n  | 
|    304  |    348  | 
|    305 for (p <- lst) yield p._1 + p._2  |    349 for (p <- lst) yield p._1 + p._2  | 
|    306  |    350  | 
|    307  |    351  | 
|    308 // general pattern |    352 // general pattern of for-yield | 
|    309  |    353  | 
|    310 for (x <- ...) yield { |    354 for (p <- ...) yield { | 
|    311   // potentially complicated |    355   // potentially complicated | 
|    312   // calculation of a result |    356   // calculation of a result | 
|    313 } |    357 } | 
|    314  |    358  | 
|    315  |    359 // Functions producing multiple outputs | 
|         |    360 //====================================== | 
|         |    361  | 
|         |    362 def get_ascii(c: Char) : (Char, Int) = (c, c.toInt) | 
|         |    363  | 
|         |    364 get_ascii('a') | 
|         |    365  | 
|         |    366  | 
|         |    367 // .maxBy, sortBy with pairs | 
|         |    368 def get_length(s: String) : (String, Int) = (s, s.length)  | 
|         |    369  | 
|         |    370 val lst = List("zero", "one", "two", "three", "four", "ten") | 
|         |    371 val strs = for (s <- lst) yield get_length(s) | 
|         |    372  | 
|         |    373 strs.sortBy(_._2) | 
|         |    374 strs.sortBy(_._1) | 
|         |    375  | 
|         |    376 strs.maxBy(_._2) | 
|         |    377 strs.maxBy(_._1) | 
|         |    378  | 
|         |    379  | 
|         |    380 // For without yield | 
|         |    381 //=================== | 
|    316  |    382  | 
|    317 // with only a side-effect (no list is produced), |    383 // with only a side-effect (no list is produced), | 
|    318 // has no "yield" |    384 // has no "yield" | 
|    319  |    385  | 
|    320 for (n <- (1 to 10)) println(n) |    386 for (n <- (1 to 10)) println(n) | 
|    348 val list = (1 to 1000000).toList |    414 val list = (1 to 1000000).toList | 
|    349 time_needed(10, for (n <- list) yield n + 42) |    415 time_needed(10, for (n <- list) yield n + 42) | 
|    350 time_needed(10, for (n <- list.par) yield n + 42) |    416 time_needed(10, for (n <- list.par) yield n + 42) | 
|    351  |    417  | 
|    352  |    418  | 
|    353 // Function producing multiple outputs |    419  | 
|    354 //===================================== |    420 // Just for "Fun": Mutable vs Immutable | 
|    355  |    421 //======================================= | 
|    356 def get_ascii(c: Char) : (Char, Int) = (c, c.toInt) |    422 // | 
|    357  |    423 // - no vars, no ++i, no += | 
|    358 get_ascii('a') |    424 // - no mutable data-structures (no Arrays, no ListBuffers) | 
|    359  |    425  | 
|    360  |    426  | 
|    361  |    427 // Q: Count how many elements are in the intersections of two sets? | 
|    362 // .maxBy, sortBy with pairs |    428  | 
|    363 def get_length(s: String) : (String, Int) = (s, s.length)  |    429 def count_intersection(A: Set[Int], B: Set[Int]) : Int = { | 
|    364  |    430   var count = 0 | 
|    365 val lst = List("zero", "one", "two", "three", "four", "ten") |    431   for (x <- A; if (B contains x)) count += 1  | 
|    366 val strs = for (s <- lst) yield get_length(s) |    432   count | 
|    367  |    433 } | 
|    368 strs.sortBy(_._2) |    434  | 
|    369 strs.sortBy(_._1) |    435 val A = (1 to 1000).toSet | 
|    370  |    436 val B = (1 to 1000 by 4).toSet | 
|    371 strs.maxBy(_._2) |    437  | 
|    372 strs.maxBy(_._1) |    438 count_intersection(A, B) | 
|         |    439  | 
|         |    440 // but do not try to add .par to the for-loop above | 
|         |    441  | 
|         |    442  | 
|         |    443 //propper parallel version | 
|         |    444 def count_intersection2(A: Set[Int], B: Set[Int]) : Int =  | 
|         |    445   A.par.count(x => B contains x) | 
|         |    446  | 
|         |    447 count_intersection2(A, B) | 
|         |    448  | 
|         |    449  | 
|         |    450 //for measuring time | 
|         |    451 def time_needed[T](n: Int, code: => T) = { | 
|         |    452   val start = System.nanoTime() | 
|         |    453   for (i <- (0 to n)) code | 
|         |    454   val end = System.nanoTime() | 
|         |    455   (end - start) / 1.0e9 | 
|         |    456 } | 
|         |    457  | 
|         |    458 val A = (1 to 1000000).toSet | 
|         |    459 val B = (1 to 1000000 by 4).toSet | 
|         |    460  | 
|         |    461 time_needed(10, count_intersection(A, B)) | 
|         |    462 time_needed(10, count_intersection2(A, B)) | 
|         |    463  | 
|    373  |    464  | 
|    374 // Further Information |    465 // Further Information | 
|    375 //===================== |    466 //===================== | 
|    376  |    467  | 
|    377 // The Scala home page and general information is at |    468 // The Scala homepage and general information is at | 
|    378 // |    469 // | 
|    379 //  http://www.scala-lang.org |    470 //  http://www.scala-lang.org | 
|    380 //	http://docs.scala-lang.org |    471 //	http://docs.scala-lang.org | 
|    381 // |    472 // | 
|    382 // |    473 // | 
|    383 // It should be fairly easy to install the Scala binary and |    474 // It should be fairly easy to install the Scala binary and | 
|    384 // run Scala on the commandline. There are also at least  |    475 // run Scala on the commandline. People also use Scala with  | 
|    385 // four IDEs you can use with Scala: |    476 // Vim and Jedit. I currently settled on VS Code | 
|    386 // |    477 // | 
|    387 //  (0) Some general information about setting up IDEs |    478 //   https://code.visualstudio.com | 
|    388 //	    with Scala support can be found at |    479 // | 
|    389 // |    480 // There are also plugins for Eclipse and IntelliJ - YMMV. | 
|    390 //         http://docs.scala-lang.org/getting-started.html  |    481 // Finally there are online editors specifically designed for  | 
|    391 // |    482 // running Scala applications (but do not blame me if you lose  | 
|    392 // |    483 // all what you typed in): | 
|    393 //  (1) Eclipse for Scala (one big bundle) |    484 // | 
|    394 // |    485 //   https://scalafiddle.io  | 
|    395 //         http://scala-ide.org/download/sdk.html |    486 //   https://scastie.scala-lang.org | 
|    396 //   |    487 // | 
|    397 //  (2) IntelliJ (needs additional Plugins) |         | 
|    398 // |         | 
|    399 //         https://www.jetbrains.com/idea/ |         | 
|    400 //		   http://docs.scala-lang.org/getting-started-intellij-track/getting-started-with-scala-in-intellij.html	   |         | 
|    401 // |         | 
|    402 //  (3) Sublime (not free, but unlimited trial period;  |         | 
|    403 //	    needs Scala and SublimeREPL plugin) |         | 
|    404 // |         | 
|    405 //         https://www.sublimetext.com |         | 
|    406 // |         | 
|    407 //  (4) Emacs (old-fashioned, but reliable) |         | 
|    408 // |         | 
|    409 //         https://www.gnu.org/software/emacs/ |         | 
|    410 // |         | 
|    411 //      I use the old scala-tool support for Emacs distributed at |         | 
|    412 // |         | 
|    413 //         https://github.com/scala/scala-tool-support/tree/master/tool-support/emacs  |         | 
|    414 // |         | 
|    415 //      but there is also support for the newer Ensime Scala Mode |         | 
|    416 // |         | 
|    417 //         http://ensime.org/editors/emacs/scala-mode/    |         | 
|    418 //    |         | 
|    419 // There is also Scala support in the Atom editor, but my |         | 
|    420 // experience is mixed. People also use Scala with Vim and Jedit. |         | 
|    421 // Finally there is an online editor specifically designed for  |         | 
|    422 // running Scala applications (but do not blame mne if you lose all  |         | 
|    423 // what you typed in): |         | 
|    424 // |         | 
|    425 //      https://scalafiddle.io  |         | 
|    426 // |         | 
|    427 // |         | 
|    428 // |         | 
|    429 // All of the IDEs above support a REPL for Scala. Some of them have |         | 
|    430 // the very nifty feature of a Scala Worksheet -- you just save your |         | 
|    431 // file and it will be automatically evaluated and the result pasted |         | 
|    432 // into your file. However, this way of writing Scala code never worked |         | 
|    433 // for me. I just use the REPL. |         | 
|    434 // |    488 // | 
|    435 // |    489 // | 
|    436 // Scala Library Docs |    490 // Scala Library Docs | 
|    437 //==================== |    491 //==================== | 
|    438 // |    492 // |