Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lazy Evaluation em Scala

Lazy Evaluation em Scala

Presented at: TDC 2012, July/2012.

Pedro Matiello

July 07, 2012
Tweet

More Decks by Pedro Matiello

Other Decks in Programming

Transcript

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

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

      f(x) = x²
  3. •A avaliação da expressão é atrasada até que o valor

    seja necessário (non-strict evaluation)
  4. def condicao1 = { println("Avaliou condicao1"); true } def condicao2

    = { println("Avaliou condicao2"); false } def condicao3 = { println("Avaliou condicao3"); true } SHORT-CIRCUIT EVALUATION
  5. 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
  6. 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
  7. 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)
  8. def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } CALL BY NAME
  9. def loop(condicao: => Boolean)(expressao: => Unit) { if (condicao) {

    expressao loop(condicao)(expressao) } } CALL BY NAME
  10. 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
  11. 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
  12. 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)
  13. 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
  14. 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. 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
  16. 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
  17. 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
  18. 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
  19.  QDWXUDLV   scala> lazy val naturais:List[Int] = 0

    :: naturais.map(_+1) naturais: List[Int] = <lazy> STREAMS
  20.  QDWXUDLV    scala> lazy val naturais:List[Int] =

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

    = 0 :: naturais.map(_+1) naturais: List[Int] = <lazy> STREAMS
  22. 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
  23. 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
  24. 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
  25. 1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) EAGER
  26. 1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) y=2 EAGER
  27. 1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) y=2, x=2 EAGER
  28. 1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) y=3, x=2 EAGER
  29. 1 var y = 2 2 val x = y

    3 y = 3 4 println("x = " + x) x = 2 y=3, x=2 EAGER
  30. 1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) LAZY
  31. 1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) y=2 LAZY
  32. 1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) y=2, x=y LAZY
  33. 1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) y=3, x=y LAZY
  34. 1 var y = 2 2 lazy val x =

    y 3 y = 3 4 println("x = " + x) x = 3 y=3, x=3 LAZY
  35. 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
  36. 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
  37. 1 val x = { throw new RuntimeException; 5 }

    2 println("x + 3 =") 3 println(x+3) EAGER
  38. 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
  39. 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
  40. 1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) LAZY
  41. 1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) LAZY
  42. 1 lazy val x = { throw new RuntimeException; 5

    } 2 println("x + 3 =") 3 println(x+3) x + 3 = LAZY
  43. 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
  44. 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