diff --git a/exercises/exercise-1.md b/exercises/exercise-1.md index b22fc74934d622633d5b4b7d0ea23063a3d8f00a..11ddb4aa11efe1c44e106b79516f5bf0b6a6facd 100644 --- a/exercises/exercise-1.md +++ b/exercises/exercise-1.md @@ -1,4 +1,4 @@ -# Exercise 1 +# Exercise Session 1 # Problem 1: Introduction to Concurrency diff --git a/exercises/exercise-2.md b/exercises/exercise-2.md index bc51fbe2d9b39816cd9ec6197f150b27b64c0729..17ba314b7dfb00d9ff36fcc98325c7dd74c3b75f 100644 --- a/exercises/exercise-2.md +++ b/exercises/exercise-2.md @@ -1,4 +1,4 @@ -# Exercise 2 +# Exercise Session 2 # Problem 1: Aggregate diff --git a/exercises/exercise-4.md b/exercises/exercise-4.md index f82f15c9552749e2667ae513a99f01564deeb6f5..cb1a551e6dcd2cd6764a773246ad20580df55c1b 100644 --- a/exercises/exercise-4.md +++ b/exercises/exercise-4.md @@ -1,4 +1,5 @@ -# Exercise 4 +# Exercise Session 4 + ## Problem 1: Implementing `map` and `filter` on Futures In this exercise, you will come up with an implementation of the `map` and `filter` methods of `MyFuture`. The `MyFuture` trait is a simplified version of the `Future` trait from the Scala standard library, with a single abstract method: diff --git a/exercises/exercise-5.md b/exercises/exercise-5.md new file mode 100644 index 0000000000000000000000000000000000000000..f4ff9ff16f2950260fcc96dc816c73fcbf56d446 --- /dev/null +++ b/exercises/exercise-5.md @@ -0,0 +1,74 @@ +# Exercise Session 5 + +## Problem 1: Message Processing Semantics + +Consider the following actor system: + +```scala +enum Protocol: + case Write(value: Int) + case Read(requester: ActorRef) +import Protocol.* + +enum Responses: + case Answer(value: Int) +import Responses.* + + +class Memory extends Actor: + var value = 0 + + override def receive: Receive = { + case Write(newValue) => value = newValue + case Read(requester) => requester ! Answer(value) + } + +class Client(memory: ActorRef) extends Actor: + override def receive: Receive = { case Answer(value) => + println(value) + } + +class MyProxy(memory: ActorRef) extends Actor: + override def receive: Receive = { case message => + memory ! message + } +``` + +### Problem 1.1 + +And the following test: + +```scala +@main def problem1_1 = + for _ <- 1 to 1000 do + val system = ActorSystem("example") + try + val memory = system.actorOf(Props(Memory())) + val client = system.actorOf(Props(Client(memory))) + memory ! Write(1) + memory ! Read(client) + finally system.terminate() +``` + +What are the possible values printed by the `println` command in the `Client` actor? Why? + +### Problem 1.2 + +Now, consider the following test: + +```scala +@main def problem1_2 = + for _ <- 1 to 1000 do + val system = ActorSystem("example") + try + val memory = system.actorOf(Props(Memory())) + val proxy = system.actorOf(Props(MyProxy(memory))) + val client = system.actorOf(Props(Client(memory))) + proxy ! Read(client) + memory ! Write(1) + finally system.terminate() +``` + +1. What are the possible values printed by the `println` command in the `Client2` actor? Why? +2. Would the output be different if the commands annotated with `XXX` were issued in the other order? +3. What if both messages are sent through the `Proxy` actor?