2

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

RDM
  • 4,986
  • 4
  • 34
  • 43

1 Answers1

1

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.

wmeyer
  • 3,426
  • 1
  • 18
  • 26
  • I think I understand everything but one thing... In step 3 you replace the current tail (unbound) with X | new tail (of which new tail is also unbound). But how can you bind the tail if it is declared as a read only variable? – RDM Apr 14 '12 at 23:10
  • Oh wait I think I got it... you don't define the tail as read only but you return the stream as a read only view of the list, right? So the stream object is the entire list and the cell keeps track of the tail so you can bind to the end of the stream using unification. I think that's how it works, correct me if I'm wrong :D – RDM Apr 15 '12 at 01:21