質問

I'm taking a teach-yourself course at the university at the moment and noticed I bitten off a bit more than I can chew. The course is about the Oz programming language and I'm reading an e-book about it to try to get to know it better and I'm trying to solve some exercises to test my understanding. I'm quite stuck at a certain exercise and I don't quite know how to solve it. The question goes:

Implementing ports. In Chapter 5 we introduced the concept of port, which is a simple communication channel. Ports have the operations {NewPort S P}, which returns a port P with stream S, and {Send P X}, which sends message X on port P. From these operations, it is clear that ports are a stateful unbundled ADT. For this exercise, implement ports in terms of cells, using the techniques of Section 6.4.

The key words are stateful unbundled and cells. I tried to implement the behavior of ports using cells with the following approach:

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}

My final step would be to add a wrapper/unwrapper pair to make the ADT secure but first I want the functionality to work properly. This seems to do the right behavior but it's not as I had wanted it. I would like to be able to call {Browse MyStream}, without the @, just once. I was hoping the browser would display something along the lines of firstSent|secondSent|_<future> instead it displays <Cell> as is to be expected and I need to call Browse to it after each Send, and the output is shown as a list: [firstSent secondSent].

If I remember correctly from the theory I read, this has to do with eager vs lazy evaluation, respectively resulting in (finite) lists vs (infinite) streams.

I have the feeling I'm not doing it quite right though and I have no experience whatsoever with functional languages, can anyone help me out with making an example of a port implemented with cells? (basically your own implementation of the existing NewPort and Send)

Thanks in advance

役に立ちましたか?

解決

A stream is just a list with an unbound tail. E.g. initially the list is just an unbound variable _. Whenever an element is sent, the tail is bound to a new pair, e.g.:

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

The tail always stays unbound unless you close the port.

Now you use the cell like a pointer to the end of the list. Initially the cell just points to S. The SendEx operation then consists of these steps:

(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.

Hope this helps.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top