1

I'm trying to figure out how to "simulate" a Port using cells but I can't make it.

The main idea is to have a function or procedure that simulates {NewPort S P} and other one that simulates {Send P X} behavior.

Here what I got.

declare P S
proc {CellPort ?P}
   P = {NewCell S}
end
proc {SendMessage P X}
   P := X | @P
   {Browse @P}
end
in
{CellPort P}
{Browse @P}
{SendMessage P c}
{SendMessage P b}
{SendMessage P a}

The Port should work like:

_
c|_
c|b|_
c|b|a|_

I don't know what else I am doing wrong that I can't make it print like above. Also, how would be implementing a cell using ports? Any guide?

Thanks in advance.

Sean Sabe
  • 79
  • 9

1 Answers1

1

Your function SendMessage builds a stream backwards.

P := X | @P

X is attached as a head to the existing stream. So your test code will create a stream

a|b|c|_

Instead, your program should add X to the unbound end of the stream. Namely, it should bind a variable inside cell P to a list pair which head is X and which tail is a new variable, a new unbound end of the stream. So a stream reader (a thread) can read a stream from its head to its tail. This is also described in Chapter “5.1.2 Semantics of ports” in the book by Peter Van Roy and Seif Haridi. A code for this is

proc {SendMessageWrong P X} End1 in
  @P = X | End1 % Line 1
  P := End1 % Line 2
end

Another issue with your code and SendMessageWrong: cell update is not atomic. Imagine what will happen when a thread executes the first line of SendMessageWrong, then another thread executes the first line of SendMessageWrong. A correct way to make it atomic is to use the built-in Exchange procedure.

{Exchange P (X | End1) End1}
beroal
  • 369
  • 4
  • 14