From 62636e844f26b2b1e584b2fd8f2b78ef758d8711 Mon Sep 17 00:00:00 2001 From: Matt Bovel <matthieu@bovel.net> Date: Tue, 17 May 2022 15:25:08 +0200 Subject: [PATCH] Add exercises 5 --- exercises/exercise-1.md | 2 +- exercises/exercise-2.md | 2 +- exercises/exercise-4.md | 3 +- exercises/exercise-5.md | 74 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 exercises/exercise-5.md diff --git a/exercises/exercise-1.md b/exercises/exercise-1.md index b22fc74..11ddb4a 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 bc51fbe..17ba314 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 f82f15c..cb1a551 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 0000000..f4ff9ff --- /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? -- GitLab