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. LAZY EVALUATION
    EM SCALA

    View full-size slide

  2. Pedro Matiello
    [email protected]
    @pmatiello
    LAZY EVALUATION
    EM SCALA

    View full-size slide

  3. •Tipagem estática
    •Programação orientada a objetos
    •Programação funcional

    View full-size slide

  4. PROGRAMAÇÃO FUNCIONAL

    View full-size slide

  5. •A operação fundamental é a aplicação de funções

    View full-size slide

  6. •Um programa é uma função
    •Normalmente composta de outras funções
    •A entrada são os argumentos
    •A saída é o valor devolvido

    View full-size slide

  7. •Transparência referencial (referential transparency)
    •A aplicação de uma função não produz efeitos
    colaterais

    View full-size slide

  8. •Funções de ordem superior (higher-order functions)
    •Avaliação atrasada (lazy evaluation)

    View full-size slide

  9. LAZY EVALUATION

    View full-size slide

  10. •A avaliação da expressão é atrasada até que o
    valor seja necessário (non-strict evaluation)

    View full-size slide

  11. •Avaliações repetidas são evitadas (sharing)

    View full-size slide

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

    View full-size slide

  13. 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

    View full-size slide

  14. 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

    View full-size slide

  15. 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)

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  18. 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

    View full-size slide

  19. 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

    View full-size slide

  20. 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)

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  26. scala> lazy val x = { println("avaliou x"); "XXX" }
    x: java.lang.String =
    scala> lazy val y = { println("avaliou y"); "YYY" }
    y: java.lang.String =
    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

    View full-size slide

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

    View full-size slide

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

    View full-size slide


  29. QDWXUDLV


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

    View full-size slide


  30. QDWXUDLV


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

    View full-size slide


  31. QDWXUDLV


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

    View full-size slide

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

    View full-size slide

  33. scala> lazy val naturais:List[Int] =
    0 :: naturais.map(_+1)
    naturais: List[Int] =
    scala> naturais.take(20)
    java.lang.StackOverflowError
    ! at .naturais(:7)
    ! at .naturais(:7)
    ! ...
    STREAMS

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  36. scala> lazy val naturais:Stream[Int] =
    0 #:: naturais.map(_+1)
    naturais: Stream[Int] =
    scala> naturais.take(20)
    res0: scala.collection.immutable.Stream[Int] =
    Stream(0, ?)
    STREAMS

    View full-size slide

  37. scala> lazy val naturais:Stream[Int] =
    0 #:: naturais.map(_+1)
    naturais: Stream[Int] =
    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

    View full-size slide

  38. CONTUDO, PORÉM, TODAVIA

    View full-size slide

  39. •A Lazy Evaluation e a Eager Evaluation podem
    produzir resultados diferentes

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  50. •O sharing do resultado das expressões pode elevar
    o consumo de memória

    View full-size slide

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

    View full-size slide

  52. scala> lazy val naturais:Stream[Int] =
    0 #:: naturais.map(_+1)
    naturais: Stream[Int] =
    scala> naturais.foreach{ x:Int => }
    SHARING

    View full-size slide

  53. scala> lazy val naturais:Stream[Int] =
    0 #:: naturais.map(_+1)
    naturais: Stream[Int] =
    scala> naturais.foreach{ x:Int => }
    Exception in thread "main" java.lang.OutOfMemoryError:
    Java heap space
    SHARING

    View full-size slide

  54. scala> lazy val naturais:Stream[Int] =
    0 #:: naturais.map(_+1)
    naturais: Stream[Int] =
    scala> naturais.foreach{ x:Int => }
    Exception in thread "main" java.lang.OutOfMemoryError:
    Java heap space
    SHARING

    View full-size slide

  55. •Erros podem aparecer em locais diferentes do
    código

    View full-size slide

  56. 1 val x = { throw new RuntimeException; 5 }
    2 println("x + 3 =")
    3 println(x+3)
    EAGER

    View full-size slide

  57. 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

    View full-size slide

  58. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  62. 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

    View full-size slide

  63. 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

    View full-size slide

  64. LAZY EVALUATION
    EM SCALA
    Pedro Matiello
    [email protected]
    @pmatiello

    View full-size slide