Lazy Evaluation em Scala

66
LAZY EVALUATION EM SCALA

description

Presented at: TDC 2012, July/2012.

Transcript of Lazy Evaluation em Scala

Page 1: Lazy Evaluation em Scala

LAZY EVALUATIONEM SCALA

Page 2: Lazy Evaluation em Scala

Pedro [email protected]

@pmatiello

LAZY EVALUATIONEM SCALA

Page 3: Lazy Evaluation em Scala

SCALA

Page 4: Lazy Evaluation em Scala

•Tipagem estática

•Programação orientada a objetos

•Programação funcional

Page 5: Lazy Evaluation em Scala

PROGRAMAÇÃO FUNCIONAL

Page 6: Lazy Evaluation em Scala

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

Page 7: Lazy Evaluation em Scala

•Um programa é uma função

•Normalmente composta de outras funções

•A entrada são os argumentos

•A saída é o valor devolvido

Page 8: Lazy Evaluation em Scala

��

��

��

f(x) = x²

Page 9: Lazy Evaluation em Scala

•Transparência referencial (referential transparency)

•A aplicação de uma função não produz efeitos colaterais

Page 10: Lazy Evaluation em Scala

•Funções de ordem superior (higher-order functions)

•Avaliação atrasada (lazy evaluation)

Page 11: Lazy Evaluation em Scala

LAZY EVALUATION

Page 12: Lazy Evaluation em Scala

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

Page 13: Lazy Evaluation em Scala

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

Page 14: Lazy Evaluation em Scala

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

SHORT-CIRCUIT EVALUATION

Page 15: Lazy Evaluation em Scala

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

Page 16: Lazy Evaluation em Scala

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

scala> condicao1 && condicao1 && condicao2 && condicao3Avaliou condicao1Avaliou condicao1Avaliou condicao2res0: Boolean = false

SHORT-CIRCUIT EVALUATION

Page 17: Lazy Evaluation em Scala

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

scala> condicao1 && condicao1 && condicao2 && condicao3Avaliou condicao1Avaliou condicao1Avaliou condicao2res0: Boolean = false

SHORT-CIRCUIT EVALUATION

(não é lazy evaluation)

Page 18: Lazy Evaluation em Scala

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

CALL BY NAME

Page 19: Lazy Evaluation em Scala

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

CALL BY NAME

Page 20: Lazy Evaluation em Scala

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

Page 21: Lazy Evaluation em Scala

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

var i = 0;loop(i < 5) { println(i); i=i+1 }01234

CALL BY NAME

Page 22: Lazy Evaluation em Scala

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

var i = 0;loop(i < 5) { println(i); i=i+1 }01234

CALL BY NAME

(apenas non-strict evaluation)

Page 23: Lazy Evaluation em Scala

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

Page 24: Lazy Evaluation em Scala

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

Page 25: Lazy Evaluation em Scala

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

Page 26: Lazy Evaluation em Scala

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 yavaliou xres0: java.lang.String = XXX

LAZY VALS

Page 27: Lazy Evaluation em Scala

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 yavaliou xres0: java.lang.String = XXX

scala> if (true) x else y

LAZY VALS

Page 28: Lazy Evaluation em Scala

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 yavaliou xres0: java.lang.String = XXX

scala> if (true) x else yres1: java.lang.String = XXX

LAZY VALS

Page 29: Lazy Evaluation em Scala

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

naturais: List[Int] = <lazy>

STREAMS

Page 30: Lazy Evaluation em Scala

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

naturais: List[Int] = <lazy>

STREAMS

� QDWXUDLV�PDS�B���

QDWXUDLV�

Page 31: Lazy Evaluation em Scala

QDWXUDLV�

����

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

naturais: List[Int] = <lazy>

STREAMS

Page 32: Lazy Evaluation em Scala

QDWXUDLV�

���� �

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

naturais: List[Int] = <lazy>

STREAMS

Page 33: Lazy Evaluation em Scala

QDWXUDLV�

���� � �

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

naturais: List[Int] = <lazy>

STREAMS

Page 34: Lazy Evaluation em Scala

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

naturais: List[Int] = <lazy>

scala> naturais.take(20)

STREAMS

Page 35: Lazy Evaluation em Scala

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

Page 36: Lazy Evaluation em Scala

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

naturais: Stream[Int] = <lazy>

STREAMS

Page 37: Lazy Evaluation em Scala

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

naturais: Stream[Int] = <lazy>

scala> naturais.take(20)

STREAMS

Page 38: Lazy Evaluation em Scala

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

Page 39: Lazy Evaluation em Scala

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

naturais: Stream[Int] = <lazy>

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

STREAMS

Page 40: Lazy Evaluation em Scala

CONTUDO, PORÉM, TODAVIA

Page 41: Lazy Evaluation em Scala

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

Page 42: Lazy Evaluation em Scala

1 var y = 22 val x = y3 y = 34 println("x = " + x)

EAGER

Page 43: Lazy Evaluation em Scala

1 var y = 22 val x = y3 y = 34 println("x = " + x)

y=2

EAGER

Page 44: Lazy Evaluation em Scala

1 var y = 22 val x = y3 y = 34 println("x = " + x)

y=2, x=2

EAGER

Page 45: Lazy Evaluation em Scala

1 var y = 22 val x = y3 y = 34 println("x = " + x)

y=3, x=2

EAGER

Page 46: Lazy Evaluation em Scala

1 var y = 22 val x = y3 y = 34 println("x = " + x)

x = 2

y=3, x=2

EAGER

Page 47: Lazy Evaluation em Scala

1 var y = 22 lazy val x = y3 y = 34 println("x = " + x)

LAZY

Page 48: Lazy Evaluation em Scala

1 var y = 22 lazy val x = y3 y = 34 println("x = " + x)

y=2

LAZY

Page 49: Lazy Evaluation em Scala

1 var y = 22 lazy val x = y3 y = 34 println("x = " + x)

y=2, x=y

LAZY

Page 50: Lazy Evaluation em Scala

1 var y = 22 lazy val x = y3 y = 34 println("x = " + x)

y=3, x=y

LAZY

Page 51: Lazy Evaluation em Scala

1 var y = 22 lazy val x = y3 y = 34 println("x = " + x)

x = 3

y=3, x=3

LAZY

Page 52: Lazy Evaluation em Scala

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

Page 53: Lazy Evaluation em Scala

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

naturais: Stream[Int] = <lazy>

SHARING

Page 54: Lazy Evaluation em Scala

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

naturais: Stream[Int] = <lazy>

scala> naturais.foreach{ x:Int => }

SHARING

Page 55: Lazy Evaluation em Scala

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

Page 56: Lazy Evaluation em Scala

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

Page 57: Lazy Evaluation em Scala

•Erros podem aparecer em locais diferentes do código

Page 58: Lazy Evaluation em Scala

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

EAGER

Page 59: Lazy Evaluation em Scala

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

Page 60: Lazy Evaluation em Scala

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

Page 61: Lazy Evaluation em Scala

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

LAZY

Page 62: Lazy Evaluation em Scala

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

LAZY

Page 63: Lazy Evaluation em Scala

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

x + 3 =

LAZY

Page 64: Lazy Evaluation em Scala

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

Page 65: Lazy Evaluation em Scala

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

Page 66: Lazy Evaluation em Scala

LAZY EVALUATION EM SCALA

Pedro [email protected]

@pmatiello