奥兹的港口和小区

时间:2012-04-14 14:23:24

标签: oz

我现在正在大学读自学课程,并注意到我咬了一下比我能咀嚼的更多。该课程是关于Oz编程语言,我正在阅读一本关于它的电子书,试图更好地了解它,我正在尝试解决一些练习来测试我的理解。我一直坚持参加某项运动而且我不太清楚如何解决它。问题是:

  

实施端口。在第5章中我们介绍了端口的概念,   这是一个简单的沟通渠道。港口有运营   {NewPort S P},返回带有流S的端口P和{Send P X},   它在端口P上发送消息X.从这些操作中可以清楚地看出   端口是有状态的非捆绑式ADT。对于本练习,请实施   使用第6.4节中的技术,以单元格表示端口。

关键词是有状态的非捆绑和细胞。我尝试使用以下方法实现端口行为:

declare
MyPort
MyStream
proc {NewPortEx ?S ?P}
   P = {NewCell nil}
   S = !!P  %read only view on the cell
end
proc {SendEx P X}
   P:=X|@P  %extend the cell's content, a list, with X
end
in
{NewPortEx MyStream MyPort}
{Browse @MyStream}
{SendEx MyPort c}
{Browse @MyStream}

我的最后一步是添加一个包装器/解包器对以使ADT安全,但首先我希望功能正常工作。 这似乎做了正确的行为,但它并不像我想要的那样。我希望能够在没有{Browse MyStream}的情况下拨打@一次。我希望浏览器会显示firstSent|secondSent|_<future>的内容,而不是按预期显示<Cell>,我需要在每个Browse之后调用Send,输出显示为列表:[firstSent secondSent]

如果我从我阅读的理论中正确记得,这与预测与懒惰评估有关,分别导致(有限)列表与(无限)流。

我觉得我没有做得很好但是我对功能语言没有任何经验,有没有人可以帮助我制作一个用单元格实现的端口的例子? (基本上是您自己对现有NewPortSend

的实现

提前致谢

1 个答案:

答案 0 :(得分:1)

流只是一个带有未绑定尾部的列表。例如。最初,列表只是一个未绑定的变量_。无论何时发送元素,尾部都绑定到一对新的,例如:

(1) Initially:          S = _
(2) Send 1 to the port: S = 1|_
(3) Send 2 to the port: S = 1|2|_
etc.

除非您关闭端口,否则尾部始终保持未绑定状态。

现在您将单元格用作指向列表末尾的指针。最初,单元格指向S.然后,SendEx操作包含以下步骤:

(1) Read the current tail from the cell.
(2) Declare a new unbound variable that will serve as the new tail.
(3) Unify: current tail = X | new tail
(4) Store the new tail in the cell.

希望这有帮助。