Structs (was RE: Record selectors)

Ulf Wiger etxuwig@REDACTED
Sun Jan 19 19:28:11 CET 2003


On Sun, 19 Jan 2003, Sven-Olof Nystr|m wrote:

>Ulf Wiger writes:
> > Erlang's selective receive -- being able to pattern-match on
> > the entire message queue -- is perhaps not absolutely
> > necessary (even though it is sometimes extremely valuable),
> > but what you need to have for complex state machine
> > programming is (a) the ability to stop and wait for a
> > specific message, and (b) the ability to single out one or a
> > few senders, buffering any other messages until later.
> > (This might also be achieved by having separate channels.)
[snipped]

>I suppose you have something like this in mind:
>
>(in module lim)
>
>stop_tone() ->
>    <some pid> ! {stop, self()},
>    receive
>        {ok, <some pid>} ->
>            true
>    after ...
>    end.

Yes.

>Implementing this without selective (matching) receive
>would require the ability to create a new channel,
>something like this:
>
>stop_tone() ->
>    Ch = new_channel()  % Create a new channel
>    <some hardware> ! {stop, Ch},
>    receive(Ch) of      % Read message from channel Ch
>        ok ->
>            true
>    after ...
>    end.

Yes, except I would still call it selective receive.

>As far as I can see, the second solution introduces no new
>complications in the state machine nor any new
>dependencies. I don't know anything about the Haskell
>solution, but I wouldn't be surprised if they are doing
>something similar.

They might well be doing it like that (it was not obvious to
me how they do it.) I agree that being able to create
temporary channels solves the lim:stop_tone() problem
nicely. This is what I had in mind when I wrote:

> > (This might also be achieved by having separate channels.)

To implement it without introducing additional complexity to
your state machine, you need to be able to (a) block, and
(b) single out a specific message/sender.

There are other issues when comparing message-oriented
programming a'la the OHaskell example and state-oriented
programming a'la Erlang. One obvious advantage to the latter
is that all the protocol specifications I've seen are
described in a state-oriented fashion. It is easier to
follow such a description/program.

>It would be interesting to see examples where matching
>receive couldn't be replaced by the creation of a temporary
>channel.
>
>It seems to me that matching receive is just a way to
>compensate for Erlang's inability to create temporary
>channels...

I can't say whether Erlang ended up with pattern matching on
one message queue because Joe, Robert, Mike et al found it
too difficult to figure out how to create temporary
channels. (:

I think a single message queue and pattern matching go well
in hand with state-oriented programming. Again, the POTS
example:

speech(OtherPid) ->
    receive
        {lim, onhook} ->
            lim:disconnect_from(OtherPid),
            OtherPid ! {self(), cancel},
            idle();
        {lim, {digit, _Digit}} ->
            speech(OtherPid);
        {OtherPid, cancel} ->
            wait_on_hook(false);
        {Pid, request_connection} ->
            Pid ! {self(), reject},
            speech(OtherPid);
        Other ->
            speech(OtherPid)
    end.

Here, we react to messages from 4 different senders
(consuming and ignoring any message from anyone else). One
could of course imagine an equally concise syntax that
scanned separate channels, pattern-matching over them,
blocking if desired and necessary.

I find very little wrong with the notion of having a single
message queue.

BTW, I read the OHaskell example/comments. The reference to
resolving deadlock was something else, and I think they read
too much into the implementation of the seize message in the
Erlang POTS example. First of all, it's not a deadlock
situation:

make_call_to_B(Address, B_Pid, B_Address) ->
   receive
      seized -> ...;
      rejected -> ...;
      {seize, Pid} -> ...
   after 1000 ->
      ...
      wait_on_hook(Address, fault)
   end.

The concurrently incoming 'seize' message is from another
Pid -- not B_Pid. One could argue the program should also
handle other important messages (e.g. onhook) in this state,
and in the POTS control program that is the suggested
solution to the final exercise in the Basic Erlang Course,
the 'calling_B' state does handle other message, like for
example onhook. This is not to say that the version in the
book is necessarily unsafe. It will handle a non-normal
situation and eventually return to idle.


/Uffe
-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson Telecom AB, ATM Multiservice Networks





More information about the erlang-questions mailing list