Occasionally a computation can only be made once data is retrieved (messages are received) from two or more different data sources. For example, you can't tell whether you won the lottery until you've got your ticket number and the winning number. You can't make change for a purchase until you know the price and the amount tendered. You can't tell who wins a pushup contest until you know how many pushups each competitor completed.
Rholang has the join operator for exactly this situation. To perform a join, just use the ;
character.
for (p1Pushups <- player1; p2Pushups <- player2) {
stdout!("The winner is...")
}
When you use the join operator, neither message will be received until both messages are available.
A space exploration company wants to make sure their rocket only launches when both of two flight engineers, Alice and Bob, give the launch command. As an example, Bob would give the go ahead by sending bobLaunch!("launch")
. When both engineers give the command, the rocket can be launched.
Consider how this code might be written using the join operator that we just discussed.
One may have been tempted to solve the rocket problem by first receiving one launch command then the other.
The problem here is when Alice okay's the launch, but Bob hasn't yet. Alice should be able to change her mind, but she cannot. Imagine if she suddenly noticed a problem with the rocket, or received some bad news and wanted to abort the launch.
When using a join, she can still change her mind because the for
won't consume her launch message until Bob's message also appears and is ready to be consumed.
What code would Alice need to "par in" to retract her launch command.
-
aliceCancel!("cancel")
-
aliceLaunch!("cancel")
-
for (x <- aliceLaunch){ Nil }
I've explored the concept of joins in the context of the famous dining philosophers problem in this blog post.
In for (x <- y; a <- b){ Nil }
, which channel must be sent on first?
- y
- b
- doesn't matter
- they must be sent simultaneously
In for (x <- y; a <- b){ Nil }
, which message will be consumed first?
- x
- a
- doesn't matter
- they will be consumed simultaneously
There is a game where two players will each send a message on separate channels. Whoever sends the first message, loses, and whoever sends the second message wins. Your task here is to write the game code that will tell which player won. To play the game, players should send messages like shown.
P1!("Send any message")
P2!("Hope I win")
In this case we actually don't want to use join because we care which player went first. Hope I didn't trick you ;)
Like the comment says, you should send the messages in both orders to make sure of who wins. The easiest way to do that right now is to have one player signal the other for when to go as shown below. We'll explore this concept further in the next lesson.
Why is it possible for nobody to win the patience game as we wrote it above?
- Because both players could send messages at the same time
- The players are sending on the wrong channels
- The first block receives P2 while the second receives P1, so neither ever finishes