progs/lecture1.scala
changeset 471 135bf034ac30
parent 447 f51e593903ac
child 481 e03a0100ec46
equal deleted inserted replaced
470:86a456f8cb92 471:135bf034ac30
     3 
     3 
     4 // - List, Sets, Strings, ... 
     4 // - List, Sets, Strings, ... 
     5 // - Value assignments (val vs var)
     5 // - Value assignments (val vs var)
     6 // - How to define functions? (What is returned?)
     6 // - How to define functions? (What is returned?)
     7 // - If-Conditions
     7 // - If-Conditions
     8 
       
     9 val tmp = 0
       
    10 val result = !(tmp == 0)
       
    11 val result = if (tmp == 0) true else false
       
    12 
       
    13 //        expressions (if (tmp == 0) true else false)
       
    14 // - For-Comprehensions (guards, with/without yield)
     8 // - For-Comprehensions (guards, with/without yield)
    15 //
       
    16 //
       
    17 // - Options
       
    18 // - Higher-Order Functions (short-hand notation)
       
    19 // - maps (behind for-comprehensions)
       
    20 // - Pattern-Matching
       
    21 // - String-Interpolations
     9 // - String-Interpolations
       
    10 //
       
    11 //
       
    12 
    22 
    13 
    23 // Value assignments
    14 // Value assignments
    24 // (their names should be lower case)
    15 // (their names should be lower case)
    25 //====================================
    16 //====================================
    26 
    17 
    27 
    18 
    28 val x = 42
    19 val x = 42
    29 val y = 3 + 4 
    20 val y = 3 + 4 
    30 val z = x / y
    21 val z = x / y
    31 val x = 70
    22 val x = 70
    32 print(z)
    23 println(z)
    33 
    24 
    34 
    25 
    35 // (you cannot reassign values: z = 9 will give an error)
    26 // (you cannot reassign values: z = 9 will give an error)
    36 //var z = 9
    27 //var z = 9
    37 //z = 10
    28 //z = 10
       
    29 
    38 
    30 
    39 // Hello World
    31 // Hello World
    40 //=============
    32 //=============
    41 
    33 
    42 // an example of a stand-alone Scala file
    34 // an example of a stand-alone Scala file
    90 (1 until 10).toList
    82 (1 until 10).toList
    91 
    83 
    92 
    84 
    93 // Equality in Scala is structural
    85 // Equality in Scala is structural
    94 //=================================
    86 //=================================
    95 val a = "Dave2"
    87 val a = "Dave"
    96 val b = "Dave"
    88 val b = "Dave"
    97 
    89 
    98 if (a == b) println("Equal") else println("Unequal")
    90 if (a == b) println("Equal") else println("Unequal")
    99 
    91 
   100 Set(1,2,3) == Set(3,1,2)
    92 Set(1,2,3) == Set(3,1,2)
   149 1   // an Int
   141 1   // an Int
   150 1L  // a Long
   142 1L  // a Long
   151 1F  // a Float
   143 1F  // a Float
   152 1D  // a Double
   144 1D  // a Double
   153 
   145 
   154 // useful list methods on lists
   146 // useful methods for lists
   155 //==============================
   147 //=========================
   156 
   148 
   157 List(1,2,3,4).length
   149 List(1,2,3,4).length
   158 List(1,2,3,4).reverse
   150 List(1,2,3,4).reverse
   159 List(1,2,3,4).max
   151 List(1,2,3,4).max
   160 List(1,2,3,4).min
   152 List(1,2,3,4).min
   198 val name = "bob"
   190 val name = "bob"
   199 
   191 
   200 val name : String = "bob"
   192 val name : String = "bob"
   201 
   193 
   202 // type errors
   194 // type errors
   203 math.sqrt("64".toDouble)
   195 math.sqrt("64")
   204 
   196 
   205 // produces
   197 // produces
   206 //
   198 //
   207 // error: type mismatch;
   199 // Type Mismatch Error:
   208 // found   : String("64")
   200 //   Found   : ("64" : String)
   209 // required: Double
   201 //   Required: Double
   210 // math.sqrt("64")
   202 //
   211 
   203 
   212 
   204 
   213 // Pairs/Tuples
   205 // Pairs/Tuples
   214 //==============
   206 //==============
   215 
   207 
   243 
   235 
   244 // The general scheme for a function: you have to give a 
   236 // The general scheme for a function: you have to give a 
   245 // type to each argument and a return type of the function
   237 // type to each argument and a return type of the function
   246 //
   238 //
   247 //  def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {
   239 //  def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {
   248 //    
   240 //     ....
   249 //  }
   241 //  }
   250 
   242 
   251 
   243 
   252 
   244 
   253 // If-Conditionals
   245 // If-Conditionals
   254 //=================
   246 //=================
   255 
   247 
   256 // - Scala does not have a then-keyword
   248 // - Scala used to not have a then-keyword
   257 // - !!both if-else branches need to be present!!
   249 // - !!both if-else branches need to be present!!
   258 
   250 
   259 def fact(n: Int) : Int = 
   251 def fact(n: Int) : Int = 
   260   if (n == 0) 1 else n * fact(n - 1)
   252   if (n == 0) 1 else n * fact(n - 1)
       
   253 
       
   254 
       
   255 // Scala 3 introduced if-then-else - maybe people 
       
   256 // desperately needed it 
       
   257 def fact(n: Int) : Int = 
       
   258   if n == 0 then 1 else n * fact(n - 1)
   261 
   259 
   262 fact(5)
   260 fact(5)
   263 fact(150)
   261 fact(150)
   264 
   262 
   265 /* boolean operators
   263 /* boolean operators
   269    !      not
   267    !      not
   270    && ||  and, or
   268    && ||  and, or
   271 */
   269 */
   272 
   270 
   273 
   271 
   274 
       
   275 def fib(n: Int) : Int = {
   272 def fib(n: Int) : Int = {
   276   if (n == 0) 1 else
   273   if (n == 0) 1 else
   277     if (n == 1) 1 else fib(n - 1) + fib(n - 2)
   274     if (n == 1) 1 else fib(n - 1) + fib(n - 2)
   278 }
   275 }
   279 
   276 
   280 fib(9)
   277 fib(9)
   281 
   278 
   282 
   279 
   283 
       
   284 
       
   285 //gcd - Euclid's algorithm
   280 //gcd - Euclid's algorithm
   286 
   281 
   287 def gcd(a: Int, b: Int) : Int = {
   282 def gcd(a: Int, b: Int) : Int = {
   288   if (b == 0) a 
   283   if (b == 0) a 
   289   else  gcd(b, a % b)
   284   else  gcd(b, a % b)
   304 def average(xs: List[Int]) : Int = {
   299 def average(xs: List[Int]) : Int = {
   305   if (xs.length == 0) 0 
   300   if (xs.length == 0) 0 
   306   else xs.sum / xs.length
   301   else xs.sum / xs.length
   307 }
   302 }
   308 
   303 
       
   304 average(List(3,4,5))
   309 average(List())
   305 average(List())
   310 
   306 average(Nil)
   311 
   307 
   312 
   308 
   313 // For-Comprehensions (not For-Loops)
   309 // For-Comprehensions (not For-Loops)
   314 //====================================
   310 //====================================
   315 
   311 
   375 
   371 
   376 for (n <- (1 to 10).toList) println(n * n)
   372 for (n <- (1 to 10).toList) println(n * n)
   377 
   373 
   378 for (n <- (1 to 10).toList) yield n * n
   374 for (n <- (1 to 10).toList) yield n * n
   379 
   375 
       
   376 
   380 // BTW: a roundabout way of printing out a list, say
   377 // BTW: a roundabout way of printing out a list, say
   381 val lst = ('a' to 'm').toList
   378 val lst = ('a' to 'm').toList
   382 
   379 
   383 for (i <- (0 until lst.length)) println(lst(i))
   380 for (i <- (0 until lst.length)) println(lst(i))
   384 
   381 
   385 // Why not just? Why making your life so complicated?
   382 // ...why not just the following? Why making your life 
       
   383 // so complicated?
   386 for (c <- lst) println(c)
   384 for (c <- lst) println(c)
   387 
   385 
   388 
   386 
   389 
   387 
   390 // Functions producing multiple outputs
   388 // Functions producing multiple outputs
   412 
   410 
   413 
   411 
   414 
   412 
   415 
   413 
   416 // Aside: concurrency 
   414 // Aside: concurrency 
   417 // scala -Yrepl-class-based -cp scala-parallel-collections_2.13-0.2.0.jar 
   415 // scala-cli --extra-jars scala-parallel-collections_3-1.0.4.jar 
   418 
   416 
   419 for (n <- (1 to 10)) println(n)
   417 for (n <- (1 to 10)) println(n)
   420 
   418 
   421 import scala.collection.parallel.CollectionConverters._
   419 import scala.collection.parallel.CollectionConverters._
   422 
   420 
   429   for (i <- (0 to n)) code
   427   for (i <- (0 to n)) code
   430   val end = System.nanoTime()
   428   val end = System.nanoTime()
   431   (end - start) / 1.0e9
   429   (end - start) / 1.0e9
   432 }
   430 }
   433 
   431 
   434 val list = (1 to 1000000).toList
   432 val list = (1L to 10_000_000L).toList
   435 time_needed(10, for (n <- list) yield n + 42)
   433 time_needed(10, for (n <- list) yield n + 42)
   436 time_needed(10, for (n <- list.par) yield n + 42)
   434 time_needed(10, for (n <- list.par) yield n + 42)
   437 
   435 
   438 // ...but par does not make everything faster
   436 // ...but par does not make everything faster
   439 
   437 
   454 // But what the heck....lets try to count to 1 Mio in parallel
   452 // But what the heck....lets try to count to 1 Mio in parallel
   455 import scala.collection.parallel.CollectionConverters._
   453 import scala.collection.parallel.CollectionConverters._
   456 
   454 
   457 var cnt = 0
   455 var cnt = 0
   458 
   456 
   459 for(i <- (1 to 1000000).par) cnt += 1
   457 for(i <- (1 to 100_000).par) cnt += 1
   460 
   458 
   461 println(s"Should be 1 Mio: $cnt")
   459 println(s"Should be 100000: $cnt")
   462 
   460 
   463 
   461 
   464 
   462 
   465 // Or
   463 // Or
   466 // Q: Count how many elements are in the intersections of 
   464 // Q: Count how many elements are in the intersections of 
   467 //    two sets?
   465 //    two sets?
   468 // A; IMPROPER WAY (mutable counter)
   466 // A; IMPROPER WAY (mutable counter)
   469 
   467 
   470 def count_intersection(A: Set[Int], B: Set[Int]) : Int = {
   468 def count_intersection(A: Set[Int], B: Set[Int]) : Int = {
   471   var count = 0
   469   var count = 0
   472   for (x <- A.par; if (B contains x)) count += 1 
   470   for (x <- A.par; if B contains x) count += 1 
   473   count
   471   count
   474 }
   472 }
   475 
   473 
   476 val A = (0 to 999).toSet
   474 val A = (0 to 999).toSet
   477 val B = (0 to 999 by 4).toSet
   475 val B = (0 to 999 by 4).toSet
   486   A.par.count(x => B contains x)
   484   A.par.count(x => B contains x)
   487 
   485 
   488 count_intersection2(A, B)
   486 count_intersection2(A, B)
   489 
   487 
   490 
   488 
   491 //another bad example
   489 
   492 def test() = {
   490 // String Interpolations
   493   var cnt = 0
   491 //=======================
   494   for(i <- (1 to 1000000).par) cnt += 1
   492 
   495   println(cnt)
   493 def cube(n: Int) : Int = n * n * n
   496 }
   494 
   497 
   495 val n = 3
   498 test()
   496 println("The cube of " + n + " is " + cube(n) + ".")
   499 
   497 
   500 
   498 println(s"The cube of $n is ${cube(n)}.")
   501 
   499 
   502 // Regular Expressions (the built in ones)
   500 // or even
   503 
   501 
   504 val s = """Any so-called "politician" should respect a vote."""
   502 println(s"The cube of $n is ${n * n * n}.")
   505 print(s)
   503 
   506 
   504 // helpful for debugging purposes
   507 print("""foo""")
   505 //
   508 
   506 //     "The most effective debugging tool is still careful 
   509 val reg = """\d+""".r
   507 //          thought, coupled with judiciously placed print 
   510 
   508 //                                             statements."
   511 reg.findAllIn("bbbbaaabbbaaaccc").toList
   509 //       — Brian W. Kernighan, in Unix for Beginners (1979)
   512 reg.replaceAllIn("bbbbaaabbbaaaccc", "*")
   510 
   513 reg.replaceAllIn("bbbb0aaa1bbba2aac3cc", "_")
   511 
   514 reg.replaceAllIn("bbbb00aaa11bbba232aac33cc", "_")
   512 
   515 
   513 def gcd_db(a: Int, b: Int) : Int = {
       
   514   println(s"Function called with $a and $b.")
       
   515   if (b == 0) a else gcd_db(b, a % b)
       
   516 }
       
   517 
       
   518 gcd_db(48, 18)
       
   519 
       
   520 // you can also implement your own string interpolations
       
   521 
       
   522 extension (sc: StringContext) {
       
   523     def i(args: Any*): String = s"\t${sc.s(args:_*)}\n"
       
   524     def l(args: Any*): String = s"${sc.s(args:_*)}:\n"
       
   525 }
       
   526 
       
   527 // this allows you to write things like
       
   528 
       
   529 i"add ${3+2}" 
       
   530 l"some_fresh_name"
   516 
   531 
   517 // Further Information
   532 // Further Information
   518 //=====================
   533 //=====================
   519 
   534 
       
   535 // We are going to use Scala 3 and the scala-cli repl (easier to use)
       
   536 //
       
   537 //  https://scala-cli.virtuslab.org
       
   538 //
       
   539 //
   520 // The Scala homepage and general information is at
   540 // The Scala homepage and general information is at
   521 //
   541 //
   522 //  http://www.scala-lang.org
   542 //  http://www.scala-lang.org
   523 //	http://docs.scala-lang.org
   543 //	http://docs.scala-lang.org
   524 //
   544 //
   525 //
   545 //
   526 // It should be fairly easy to install the Scala binary and
   546 // It should be fairly easy to install the scala-cli binary and
   527 // run Scala on the commandline. People also use Scala with 
   547 // run Scala on the commandline. People also use Scala with 
   528 // Vim and Jedit. I currently settled on VS Code
   548 // Vim and Jedit. I currently settled on Codium
   529 //
   549 //
   530 //   https://code.visualstudio.com
   550 //   https://code.visualstudio.com
   531 //
   551 //
   532 // There are also plugins for Eclipse and IntelliJ - YMMV.
   552 // There are also plugins for Eclipse and IntelliJ - YMMV.
   533 // Finally there are online editors specifically designed for 
   553 // Finally there are online editors specifically designed for 
   540 //
   560 //
   541 //
   561 //
   542 // Scala Library Docs
   562 // Scala Library Docs
   543 //====================
   563 //====================
   544 //
   564 //
   545 //  http://www.scala-lang.org/api/current/
   565 //  https://dotty.epfl.ch/api/index.html
   546 //
   566 //
   547 // Scala Tutorials
   567 // Scala Tutorials
   548 //
   568 //
   549 //  http://docs.scala-lang.org/tutorials/
   569 //  http://docs.scala-lang.org/tutorials/
   550 //
   570 //
   551 // There are also a massive number of Scala tutorials on youtube
   571 // There are also a massive number of Scala tutorials on youtube
   552 // and there are tons of books and free material. Google is your 
   572 // and there are tons of books and free material. Google is your 
   553 // friend.
   573 // friend. Just make sure you follow newer material about Scala 3.
   554 
   574 
   555 
   575