[e-lang] [Fwd: Re: Proposal: E / Erlang integration]

Mark S. Miller markm@REDACTED
Fri Jun 9 09:37:02 CEST 2006


David Hopwood wrote:
> If the intent is to delay any messages until we get out of the waiting state, then
> the following would work (but would be inefficient, as discussed in the earlier
> thread at <http://www.erlang.org/ml-archive/erlang-questions/200507/msg00301.html>):
> 
>           bind waiting {
>               match [verb, args] { E.send(pots, verb, args) }
>           }
> 
> Hmm, maybe selective receive would be beneficial here. I don't think it is
> incompatible with the rest of E's concurrency model, 


It is certainly not incompatible, and can be done in E without the polling 
loop above. Everywhere that David's code uses the pattern

              state := waiting
              when (lim <- msg(..)) -> {
                  state := new_state
              }

change it to say instead

              def [promise, resolver] := Ref.promise()
              state := promise
              when (lim <- msg(..)) -> {
                  state := new_state
                  resolver.resolve(pots)
              }

In other words, while we're waiting for a response from lim, 'state' holds a 
promise. Messages eventually sent to this promise (here, by E.send(..)) are 
queued up in the promise. Once we obtain a response from lim, we set state to 
the new state, and we resolve this promise to be pots, releasing all these 
queued up messages to be delivered, preserving relative order, initially 
according to this new state. With this pattern, we no longer need the waiting 
state.

However, let's remember the original question. It seems both models can be 
implemented in both languages. Erlang supports selective receive more 
naturally. E supports non-blocking event-loops more naturally. Above, we 
implemented selective receive in E, effectively simulating Erlang's selective 
receive. If this is indeed the best solution to the problem, and it might be, 
then we have a clear case where Erlang made the programmer's life simpler but 
E made it more complex. Is there a better solution that's more natural for 
non-blocking event loops? I don't know.


> OTOH, I'm not entirely convinced that buffering messages until we leave the
> waiting state (as the Erlang code implicitly does) is exactly the right thing.
> For example, if we get an 'offhook' message, or if the hardware fails, then the
> message buffer should be flushed. I don't think there's any way to do that in
> Erlang (there is with the receptionist approach).


IIUC the behavior you're suggesting, the hardware failure case could be coded 
in E as:

              def [promise, resolver] := Ref.promise()
              state := promise
              when (lim <- msg(..)) -> {
                  state := new_state
                  resolver.resolve(pots)
              } catch problem {
                  resolver.smash(problem)
              }

As explained in section 18.1 (p. 149) of 
<http://www.cypherpunks.to/erights/talks/thesis/markm-thesis.pdf>, this can 
also be written in E as

              state := when (lim <- msg(..)) -> {
                  state := new_state
                  pots
              }

This causes all messages received while 'state' was a promise to be discarded, 
and causes any promises for the results of these messages to be likewise 
broken, discarding any messages sent to those promises, etc. As for whether 
this is realistic or appropriate for this problem domain, I have no idea. Is it?

-- 
Text by me above is hereby placed in the public domain

     Cheers,
     --MarkM



More information about the erlang-questions mailing list