Standalone examples shown in the book Practical FP in Scala: A hands-on approach.
second-edition
branch, which is the new default.
:izakaya_lantern: Standalone examples shown in the book "Practical FP in Scala: A hands-on approach"
Home Page: https://leanpub.com/pfp-scala
License: Apache License 2.0
Standalone examples shown in the book Practical FP in Scala: A hands-on approach.
second-edition
branch, which is the new default.
First edition, ch.2 "Shared state", p. 37, "Regions of sharing".
The following code snippet from the book looks incorrect:
import cats.effect._
import cats.effect.concurrent.Semaphore
import cats.effect.implicits._
import cats.implicits._
import scala.concurrent.duration._
object SharedState extends IOApp {
// Not present in the book, added for compilability
def putStrLn(str: String): IO[Unit] = IO(println(str))
def someExpensiveTask: IO[Unit] = {
IO.sleep(1.second) >> putStrLn("expensive task") >> someExpensiveTask
}
def p1(s: Semaphore[IO]): IO[Unit] = s.withPermit(someExpensiveTask) >> p1(s)
def p2(s: Semaphore[IO]): IO[Unit] = s.withPermit(someExpensiveTask) >> p2(s)
override def run(args: List[String]): IO[ExitCode] =
Semaphore[IO](1).flatMap { sem =>
p1(sem).start.void *> p2(sem).start.void
} *>
IO.never.as(ExitCode.Success)
}
someExpensiveTask
definition is recurring, whereas the snippet semantics assumes recurrence only at p1
and p2
definitions.
What actually happens is that p2
locks the semaphore and launches an infinite loop of someExpensiveTask
executing itself recursively. The very first withPermit
call is never finished and the semaphore is never unlocked.
What the author probably meant is:
def someExpensiveTask: IO[Unit] = {
IO.sleep(1.second) >> putStrLn("expensive task")
}
For the sake of visualization I have also changed the code a bit to explicitly illustrate, whether p1
or p2
called the task:
def someTask(x:Int): IO[Unit] = {
IO.sleep(1.second) >> putStrLn("SomeTask called by " ++ x.toString)
}
def p1(s:Semaphore[IO]):IO[Unit] = s.withPermit(someTask(1)) >> p1(s)
def p2(s:Semaphore[IO]):IO[Unit] = s.withPermit(someTask(2)) >> p2(s)
override def run(args: List[String]): IO[ExitCode] =
Semaphore[IO](1).flatMap{s => p1(s).start *> p2(s).start} *>
IO.never.as(ExitCode.Success)
In this case, output corresponds to what the reader assumes to see - a list of alternating SomeTask called by 1
and SomeTask called by 2
, which means the state sharing actually works and semaphore "owner" alternates.
Also, this code is not present in the current repo, as far as I can see.
I am trying to use examples.streams.StreamResource with the following code,
object RunMeResource extends IOApp {
override def run(args: List[String]): IO[ExitCode] =
StreamResource
.make[IO]
.use(bg => bg.schedule(IO(println("happy")), 3.second)) *>
IO.sleep(5.seconds) *> // (A)
IO.pure(ExitCode.Success)
}
but it waits for 5 seconds before it terminates without printing anything. If I remove the 5 seconds of sleep in (A) the code terminates immediately without printing anything
How do I use StreamResource the right way? Thanks
I won't say it is an issue but for the sake of request, I opened an issue. May we get any Design Diagram (UML) or Flow Diagram, that picture the whole application flow.
(Beside that, I am following the book with the code, that is super awesome, thanks for such a great content.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.