[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