progs/lecture1.scala
changeset 308 e86add5a6961
parent 273 b19227660752
child 310 335079d938aa
equal deleted inserted replaced
307:3c7ac7836e4f 308:e86add5a6961
    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 
    66 val n1 = 3 + 7
    70 val n1 = 3 + 7
    67 val n2 = 5 + 5
    71 val n2 = 5 + 5
    68 
    72 
    69 n1 == n2
    73 n1 == n2
    70 
    74 
    71 // this applies to "concrete" values;
    75 // this applies to "concrete" values...pretty much everything;
    72 // you cannot compare functions
    76 // but for example you cannot compare functions (later)
    73 
    77 
    74 
    78 
    75 // Printing/Strings
    79 // Printing/Strings
    76 //==================
    80 //==================
    77 
    81 
   106 List(1,2,3,1).toSet
   110 List(1,2,3,1).toSet
   107 
   111 
   108 "hello".toList.tail
   112 "hello".toList.tail
   109 1.toDouble
   113 1.toDouble
   110 
   114 
       
   115 1L 
       
   116 // a long
   111 
   117 
   112 // useful list methods
   118 // useful list methods
   113 
   119 
   114 List(1,2,3,4).length
   120 List(1,2,3,4).length
   115 List(1,2,3,4).reverse
   121 List(1,2,3,4).reverse
   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