Differences in computation order IO.println() #4082
-
Hi all, Here is my 1st code snippet: val tickingClock1: IO[Unit] = for {
_ <- IO.println("IO println = " + System.currentTimeMillis())
_ <- IO.sleep(1.second)
_ <- tickingClock1
} yield () It produces this result:
When I change the order of the IO.sleep(1.second) and put it after the IO.println(...) it changes the behavior: val tickingClock2: IO[Unit] = for {
_ <- IO.sleep(1.second)
_ <- IO.println("IO println = " + System.currentTimeMillis())
_ <- tickingClock2
} yield () It produces the next result:
Why in the first snippet I get the same time every second instead of increment every second like in the second snippet ? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Take a look at the signature of def println[A](a: A)(implicit S: Show[A] = Show.fromToString[A]): IO[Unit] = ??? Note that val tmp = anExpression
IO.println(tmp) If the signature of Using this val-extraction rewrite in the definition val tickingClock1: IO[Unit] =
val tmp = "IO println = " + System.currentTimeMillis()
for {
_ <- IO.println(tmp)
_ <- IO.sleep(1.second)
_ <- tickingClock1
} yield () Because Contrast with val tickingClock2: IO[Unit] = for {
_ <- IO.sleep(1.second)
tmp = "IO println = " + System.currentTimeMillis()
_ <- IO.println(tmp)
_ <- tickingClock2
} yield () It's a bit harder to see why the extraction of val tickingClock2: IO[Unit] =
IO.sleep(1.second).flatMap { _ =>
val tmp = "IO println = " + System.currentTimeMillis()
IO.println(tmp).flatMap { _ =>
tickingClock2.map { _ =>
()
}
}
} Without the for-comprehension sugar, you can see the |
Beta Was this translation helpful? Give feedback.
Take a look at the signature of
IO.println
:Note that
a
is not a by-name parameter soIO.println(anExpression)
can be rewritten to the following without any change in evaluation order:If the signature of
println
wasdef println[A](a: => A)(implicit S: Show[A] = Show.fromToString[A]): IO[Unit]
instead, then we wouldn't be able to perform this val-extraction refactoring with changing the evaluation order, as the entire expression would be passed toprintln
instead of first being evaluated.Using this val-extraction rewrite in the definition
tickingClock1
gives us: