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 Slide

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

    View Slide

  3. SCALA

    View Slide

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

    View Slide

  5. PROGRAMAÇÃO FUNCIONAL

    View Slide

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

    View Slide

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

    View Slide













  8. f(x) = x²

    View Slide

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

    View Slide

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

    View Slide

  11. LAZY EVALUATION

    View Slide

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

    View Slide

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

    View Slide

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

    View 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
    SHORT-CIRCUIT EVALUATION

    View Slide

  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

    View Slide

  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)

    View Slide

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

    View Slide

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

    View 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 }
    CALL BY NAME

    View Slide

  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

    View Slide

  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)

    View 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 =
    LAZY VALS

    View 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 =
    LAZY VALS

    View 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
    LAZY VALS

    View 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
    LAZY VALS

    View Slide

  27. 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 Slide

  28. 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 Slide

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

    View Slide

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

    View Slide


  31. QDWXUDLV


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

    View Slide


  32. QDWXUDLV


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

    View Slide


  33. QDWXUDLV


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

    View Slide

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

    View Slide

  35. 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 Slide

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

    View Slide

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

    View Slide

  38. 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 Slide

  39. 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 Slide

  40. CONTUDO, PORÉM, TODAVIA

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  55. 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 Slide

  56. 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 Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide