Lazy Evaluation em Scala

Lazy Evaluation em Scala

Presented at: TDC 2012, July/2012.

E54f4140dc133a17200fe7a104c33a8e?s=128

Pedro Matiello

July 07, 2012
Tweet

Transcript

  1. 3.
  2. 7.

    •Um programa é uma função •Normalmente composta de outras funções

    •A entrada são os argumentos •A saída é o valor devolvido
  3. 8.

             

      f(x) = x²
  4. 12.

    •A avaliação da expressão é atrasada até que o valor

    seja necessário (non-strict evaluation)
  5. 14.

    def condicao1 = { println("Avaliou condicao1"); true } def condicao2

    = { println("Avaliou condicao2"); false } def condicao3 = { println("Avaliou condicao3"); true } SHORT-CIRCUIT EVALUATION
  6. 15.

    def condicao1 = { println("Avaliou condicao1"); true } def condicao2

    = { println("Avaliou condicao2"); false } def condicao3 = { println("Avaliou condicao3"); true } scala> condicao1 && condicao1 && condicao2 && condicao3 SHORT-CIRCUIT EVALUATION
  7. 16.

    def condicao1 = { println("Avaliou condicao1"); true } def condicao2

    = { println("Avaliou condicao2"); false } def condicao3 = { println("Avaliou condicao3"); true } scala> condicao1 && condicao1 && condicao2 && condicao3 Avaliou condicao1 Avaliou condicao1 Avaliou condicao2 res0: Boolean = false SHORT-CIRCUIT EVALUATION
  8. 17.

    def condicao1 = { println("Avaliou condicao1"); true } def condicao2

    = { println("Avaliou condicao2"); false } def condicao3 = { println("Avaliou condicao3"); true } scala> condicao1 && condicao1 && condicao2 && condicao3 Avaliou condicao1 Avaliou condicao1 Avaliou condicao2 res0: Boolean = false SHORT-CIRCUIT EVALUATION (não é lazy evaluation)
  9. 18.

    def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } CALL BY NAME
  10. 19.

    def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } CALL BY NAME
  11. 20.

    def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } var i = 0; loop(i < 5) { println(i); i=i+1 } CALL BY NAME
  12. 21.

    def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } var i = 0; loop(i < 5) { println(i); i=i+1 } 0 1 2 3 4 CALL BY NAME
  13. 22.

    def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } var i = 0; loop(i < 5) { println(i); i=i+1 } 0 1 2 3 4 CALL BY NAME (apenas non-strict evaluation)
  14. 23.

    scala> lazy val x = { println("avaliou x"); "XXX" }

    x: java.lang.String = <lazy> scala> lazy val y = { println("avaliou y"); "YYY" } y: java.lang.String = <lazy> LAZY VALS
  15. 24.

    scala> lazy val x = { println("avaliou x"); "XXX" }

    x: java.lang.String = <lazy> scala> lazy val y = { println("avaliou y"); "YYY" } y: java.lang.String = <lazy> LAZY VALS
  16. 25.

    scala> lazy val x = { println("avaliou x"); "XXX" }

    x: java.lang.String = <lazy> scala> lazy val y = { println("avaliou y"); "YYY" } y: java.lang.String = <lazy> scala> if (true) x else y LAZY VALS
  17. 26.

    scala> lazy val x = { println("avaliou x"); "XXX" }

    x: java.lang.String = <lazy> scala> lazy val y = { println("avaliou y"); "YYY" } y: java.lang.String = <lazy> scala> if (true) x else y avaliou x res0: java.lang.String = XXX LAZY VALS
  18. 27.

    scala> lazy val x = { println("avaliou x"); "XXX" }

    x: java.lang.String = <lazy> scala> lazy val y = { println("avaliou y"); "YYY" } y: java.lang.String = <lazy> scala> if (true) x else y avaliou x res0: java.lang.String = XXX scala> if (true) x else y LAZY VALS
  19. 28.

    scala> lazy val x = { println("avaliou x"); "XXX" }

    x: java.lang.String = <lazy> scala> lazy val y = { println("avaliou y"); "YYY" } y: java.lang.String = <lazy> scala> if (true) x else y avaliou x res0: java.lang.String = XXX scala> if (true) x else y res1: java.lang.String = XXX LAZY VALS
  20. 31.

     QDWXUDLV   scala> lazy val naturais:List[Int] = 0

    :: naturais.map(_+1) naturais: List[Int] = <lazy> STREAMS
  21. 32.

     QDWXUDLV    scala> lazy val naturais:List[Int] =

    0 :: naturais.map(_+1) naturais: List[Int] = <lazy> STREAMS
  22. 33.

     QDWXUDLV     scala> lazy val naturais:List[Int]

    = 0 :: naturais.map(_+1) naturais: List[Int] = <lazy> STREAMS
  23. 35.

    scala> lazy val naturais:List[Int] = 0 :: naturais.map(_+1) naturais: List[Int]

    = <lazy> scala> naturais.take(20) java.lang.StackOverflowError ! at .naturais(<console>:7) ! at .naturais(<console>:7) ! ... STREAMS
  24. 38.

    scala> lazy val naturais:Stream[Int] = 0 #:: naturais.map(_+1) naturais: Stream[Int]

    = <lazy> scala> naturais.take(20) res0: scala.collection.immutable.Stream[Int] = Stream(0, ?) STREAMS
  25. 39.

    scala> lazy val naturais:Stream[Int] = 0 #:: naturais.map(_+1) naturais: Stream[Int]

    = <lazy> scala> naturais.take(20).toList res1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) STREAMS
  26. 42.

    1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) EAGER
  27. 43.

    1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) y=2 EAGER
  28. 44.

    1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) y=2, x=2 EAGER
  29. 45.

    1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) y=3, x=2 EAGER
  30. 46.

    1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) x = 2 y=3, x=2 EAGER
  31. 47.

    1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) LAZY
  32. 48.

    1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) y=2 LAZY
  33. 49.

    1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) y=2, x=y LAZY
  34. 50.

    1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) y=3, x=y LAZY
  35. 51.

    1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) x = 3 y=3, x=3 LAZY
  36. 54.
  37. 55.

    scala> lazy val naturais:Stream[Int] = 0 #:: naturais.map(_+1) naturais: Stream[Int]

    = <lazy> scala> naturais.foreach{ x:Int => } Exception in thread "main" java.lang.OutOfMemoryError: Java heap space SHARING
  38. 56.

    scala> lazy val naturais:Stream[Int] = 0 #:: naturais.map(_+1) naturais: Stream[Int]

    = <lazy> scala> naturais.foreach{ x:Int => } Exception in thread "main" java.lang.OutOfMemoryError: Java heap space SHARING
  39. 58.

    1 val x = { throw new RuntimeException; 5 }

    2 println("x + 3 =") 3 println(x+3) EAGER
  40. 59.

    1 val x = { throw new RuntimeException; 5 }

    2 println("x + 3 =") 3 println(x+3) Exception in thread "main" java.lang.RuntimeException ! at Test$.main(Test.scala:1) ! at Test.main(Test.scala) EAGER
  41. 60.

    1 val x = { throw new RuntimeException; 5 }

    2 println("x + 3 =") 3 println(x+3) Exception in thread "main" java.lang.RuntimeException ! at Test$.main(Test.scala:1) ! at Test.main(Test.scala) EAGER
  42. 61.

    1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) LAZY
  43. 62.

    1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) LAZY
  44. 63.

    1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) x + 3 = LAZY
  45. 64.

    1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) x + 3 = Exception in thread "main" java.lang.RuntimeException ! at Test$.main(Test.scala:1) ! at Test$.main(Test.scala:3) ! at Test.main(Test.scala) LAZY
  46. 65.

    1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) x + 3 = Exception in thread "main" java.lang.RuntimeException ! at Test$.main(Test.scala:1) ! at Test$.main(Test.scala:3) ! at Test.main(Test.scala) LAZY