Mike Stay's Tutorial

From Rholang Wiki
Jump to navigation Jump to search

Mike Stay of Pyrofex wrote the first rholang tutorial in early 2018. It was hosted throughout 2018 at developer.rchain.coop/tutorial but later disappeared. The content is integrated into https://github.com/rchain/rchain/blob/916800aa289b2feb43958621f6b57d2b1f4412c4/docs/rholang/rholangtut.md and reproduced in this wiki.

Examples from the Tutorial[edit]

TODO Make these each individual pages?

Make Cell[edit]

 1 new MakeCell in {
 2   // Makes a single cell in which you can store values
 3   contract MakeCell(@init, get, set) = {
 4     new valueStore in {
 5       valueStore!(init) |
 6       contract get(ack) = {
 7         for(@value <- valueStore) {
 8           valueStore!(value) | ack!(value)
 9         }
10       } |
11       contract set(@newValue, ack) = {
12         for(_ <- valueStore) {
13           valueStore!(newValue) | ack!(true)
14         }
15       }
16     }
17   } |
18   // Cell usage.
19   new myGet, mySet in {
20     MakeCell!(123, *myGet, *mySet) |
21     new ack in {
22       myGet!(*ack) |
23       for (@result <- ack) {
24         //result now contains the value 123
25         mySet!(456, *ack) |
26         for (_ <- ack) {
27           myGet!(*ack) |
28           for (@result <- ack) {
29             //result now contains the value 456
30             Nil
31           }
32         }
33       }
34     }
35   }
36 }

1. We create a new channel MakeCell and then use it on line 3 as the name of an internal contract. No process other than the code inside this lexical scope can invoke it.

3. The MakeCell contract takes three arguments. The first argument is the initial value to be stored in the cell. The second and third arguments are channels over which the cell will receive requests to get and set the value. Note that we want the first argument to be a process and the second and third to be names, but names are always received over channels so we need to make the first argument a pattern beginning with @ to indicate that the name we receive as the first argument is a quoted process and it is that process which we want to bind to the variable.

4. To store the value, we create a new channel. This channel will have at most one message on it containing the current value of the cell.

5. Before this line, there are no messages on the valueStore channel. After we send the initial value, it is the only value on that channel.

6. We set up a contract to listen on the get channel. Each time a message is sent on get, the body of the contract will be executed

7. We block until we get one message from the valueStore channel. Because there is at most one message ever waiting on valueStore, reading the message behaves much like acquiring a lock.

8. We send the current value on valueStore again, allowing other messages to be processed (i.e. releasing the lock), and we send the current value back to the client on the ack channel.

11. Concurrently with the get contract, we run a contract listening on set.

12. We block until there's a message on valueStore, then read it. We throw away the message that we read.

13. We send the new value to store on valueStore and signal that the operation is complete.

18-36) The usage code demonstrates creating a cell, assigning the initial value 123, getting that value, setting the value to 456, then getting that value.

Note the deep layers of callback. Rholang was designed to make concurrent computations natural to express; as a consequence, data dependencies implicit in sequencing in other languages must be made explicit.


Coat check[edit]

Dining Philosophers[edit]

See main article Dining Philosophers

Attenuating Forwarders[edit]