打印

通过示例学习rholang(课程3-5)

[复制链接]
756|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
课程3 -- 传音筒、"name"和“process”

消息传递

The game of telephone is perfect to simulate message forwarding in rholang.

在前面的章节,我们学习了如何向祖母或披萨店发送消息。但是至今所有的接收方都通过将消息打印至标准输出,来告知已经接收到了。

现在让我们做一些更有意思的事情--类似孩子们的传话游戏那样传递消息。

telephone3.rho

你可以通过运行上面的代码来做实验。你可以修改你觉得合适的地方多运行几次。

练习

传话游戏很有趣,但有更多玩家参与会更好。请添加第三位明教Charlie的玩家。bob接收消息后将发送消息给Charlie,而不是简单打印至stdout。然后Charlie将它打印至屏幕上。多多益善!

The message never seems to get there correctly. I blame Bob.

练习

如果你曾经玩过电话游戏,你应该知道,消息极少能被正确地传递。Bob现在决定通过发送一条错误的消息。改写程序,使得Bob无论收到什么,都能传递不同的消息。

*这到底是啥?

Opposites attract

你注意到 @"Bob"!(message)中的? 在rholang中有两种类型, "names" 和 "processes"。同样也有可以在两者之间互相转化的方法。

"processes"可以是rholang中任何一个代码片段,例如我们的传话筒游戏,或者是披萨店订单程序。“process”可以是上百行的大程序,也可以只有几行。它们甚至可以是用于表示值的代码。下面是一些“process”的例子。

stdout!("Sup Rholang?") 一个常见的发送操作。

Nil 最小的“process”。如字面意思,它不做任何事。

for(msg <- @"phone"){Nil} 一个常见的接收操作,在消息到达时它不会做任何事。

"Hello World" 另一个不做任何事请的小“process”。被称为"基础术语"。 "names"可以被用于赋名通道以发送消息。在大多数编程语言中,"name"是完全独立的一样东西,它们本身就存在。但是在rholang中,"name"来自"引用process",即将@标签放在“process”之前,即可得到一个"name"。下面是"name"的一些例子。

@"Hello World" 通过引用基础术语"Hello World"来创建。

@nil 最小的“name”。通过引用最小的“process”来创建。

@(@"Alice"!("I like rholang, pass it on."))

通过引用来自传话筒游戏的"process"来创建。

关于*的一切

What kind of name is that!? Did your parents just name you after some computer code?

通过用@符号来标记“process”,我们可以将“process”打包以创建一些“name”。我们也可以通过使用*标记“name”,从而将“name”转变为“process”。

在rholang中,我们需要记住的是发送“process”和接收“name”。这很重要,因此我再次强调。你总是发送一个“process”,在另一端接收一个“name”。

Aice通过for(message <- @"Alice")接收我们的消息,所以, message 变成了一个“name”。当她之后发送给Bob时,她不得不发送“process”,所以她要用@"Bob"!(message)使用将message转变回一个“process”。

小测验

我们发送什么?

processes

names

我们接收什么?

processes

names

@"registration"是什么?

process

name

非法语法

Nil是什么?

process

name

非法语法

@Nil是什么?

process

name

非法语法

@@Nil是什么?

process

name

非法语法

*importantData 是一个“process”, 那么importantData是什么?

process

name

非法语法

下面哪一个与"BobsPhone"等价?

*@"BobsPhone"

@"BobsPhone"

*"BobsPhone"

@*BobsPhone

stdout!("BobsPhone")

练习

This telephone game has a fork

不像之前的线性传话游戏那样,每个玩家将信息传递给下一位,我么来为游戏添加一个分支。现在,Bob与先前一样将发送消息给Charlie,但同时也会发送给Elise。

每个分支的长度由你定,但在每个分支的最后都得将消息打印至标准输出。

课程4 -- 持续发送与窥探

为什么要重复发送?

This radio navigation aid helps airplanes navigate by broadcasting the same message over and over

我们的披萨和咖啡店都可以在同一个复用通道中接收消息。我们使用一个持续的for (msg <= chan){...}或者一个合约contract chan(msg){...}来达成这一目的。

空中交通管制塔楼可能会乐于做刚好相反的事——不停地发送相同的消息。塔楼中的控制者希望记录同时包含天气和跑道信息的消息,并且提供给所有需要的飞行员。类似披萨店, 他们很繁忙,不会费力地在每次飞行员需要时都不停地发送信息。

持续发送的语法

控制塔需要在代码上做较小的调整,以使得发送操作能够持续。他们会使用!!而非单个!。

persistentSend.rho

请自行确认一下,原先发送的消息是否仍然在元组空间内。

练习

注意上述代码,第二名飞行员同样能够接收到信息。发送仍在持续。

对了,你注意到了吗?当我们实际上并不使用stdout时,我们不需要new stdout(...) in {}

for (x <- y) {Nil} | y!!(Nil)中有多少次通信事件发生?

1

很多次

0

二次检查消息

正如我们刚才展示的,持续性发送和接收非常有用。但是,普通的发送和接收也同样足够好了。设想这样的场景:我将一个字母发送给祖母,她接收到了这个消息。

grandma.rho

现在我们设想:我想要二次检查我是否给她发送了正确的时间。我可以简单地取出这条消息,但这样一来她就没法读取这个消息了。

练习

依据你所知道的,你可以通过获取这个消息,自行检查它,再将它发送回旧的通道,以达到我们的目的。

请自行尝试上面的方案。答案已列在下面。

for (x <= y) {Nil} | y!!(Nil)会产生多少个通信事件?

1

很多个

0

答案

grandmaCheck.rho

窥探语法

Maybe I'll just peak at Grandma's letter through the envelope.

rholang以后会为观察通道内变量提供一个特殊的语法。目前我们还不能使用它,但是下面会展示给你看这个语法的用法。我们将使用<!操作符来"窥探"一个通道内的消息。

peek.rho

如果你使用过excel的宏,或者excel,你应该对如何在不取出数据的情况下访问它感到非常熟悉。把它当做for (value <! A1) { ... }。

下列哪一个语法是用于窥探一个消息的?

for (x <! y){...}

for (x <= y){...}

x!!(y)

for (x <! y) {Nil} | y!!(Nil)会产生多少个通信事件?

1

许多

0

课程5 -- Join操作

多数据源


In general, the winner of this pushup competition can't be determined until both participants are finished.

有时候仅当从两个以上不同的数据源获取数据后,才会开始计算。例如,在你得知了你的彩票号码和中奖号码之前,你无法知道你是否赢得大奖。在你知道购买物品价格和购买总额之前,你无法进行购买。在你知道每个参赛者做了多少个俯卧撑前,你无法知道谁赢得俯卧撑比赛。

rholang提供了Join操作,来应对这种情况。使用;符号来执行一次Join操作。

for (p1Pushups <- @"player1"; p2Pushups <- @"player2") { @"stdout"!("The winner is...") }

火箭发射

一家太空探索公司想要确保,仅当两个航空工程师,Alice和Bob,都下达了发射命令后,他们的火箭才会发射。例如,Bob将通过发送BobLaunch!("launch")来下达命令。当两位工程师都下达了命令,那么火箭便可以发射。

练习

思考一下,使用我们刚提到的Join操作符,应该怎么写这个代码呢?

错误的方式

下面的例子中,其中一人先收到发射指令,并尝试处理火箭发射问题,然后再轮到另一个人。

launchBad.rho

问题在于,当Alice批准发射,而Bob还没有,Alice应该能够更改她的指令,但在此例中她不行。设想一下,如果她突然发觉火箭有一个问题,或者收到了一些不好的消息,想要停止发射。

No use in grabbing just one set of mail. Might as well wait until the second set

当使用Join时,她依然可以更改她的决定,因为for只会在双方的消息都进入通道并准备好后,才会开始取出双方的消息。

发射的解决方案

launch.rho

下列哪一段代码是Alice所需,用以撤销发射命令的?

@"AliceCancel"!("cancelZ")

@"AliceLaunch"!("cancel")

for (x <- @"AliceLaunch"){Nil}

Join的概念起初是在哲学家进餐问题中被提出,并且在这篇简短的rholang教程中(更详细的解释)[developer.rchain.coop/tutorial/#d…"]。

在for (x <- y; a <- b){ Nil }中, 应该优先向哪一个通道发送消息?

y

b

无所谓

同时被发送

在for (x <- y; a <- b){ Nil }中, 哪一条消息被优先取出?

x

a

无所谓

会被同时取出

练习

有一个比赛,两名选手将各自在各自的通道发送消息。谁第一个发送了消息,谁就输掉比 赛,第二个发送消息的人获胜。你的任务是写一段代码告诉我们谁赢了。参赛选手应按如下方式发送消息。

P1!("Send any message") P2!("Hope I win")

在这场需要靠耐心获胜竞赛这一例子中,我们不使用求并运算,因为我们在意哪个选手先行动。希望你没有陷入我的陷阱中;)

patienceSolution.rho

正如注释所说,你应该使用REPL模式运行上面的代码,然后用两种不同的顺序来发送的消息确保两个选手都获胜一次。另一个方案如下所示,让一个玩家去通知另一个玩家何时执行。我们将在下一节继续研究这种方法。

P1First.rho

在上面我们写的代码中,为什么可能出现没有人赢得这场耐心比赛?

因为两名选手可以同时发送消息

选手们在错误的通道发送消息

第一个块接收P2,而第二个块接收P1,所以代码并不能保证游戏完成

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

7

帖子

0

粉丝