[erlang-questions] style question - best way to test multiple non-guard conditions sequentially

Richard A. O'Keefe <>
Fri Jun 21 04:25:22 CEST 2013


On 21/06/2013, at 12:34 PM, Jonathan Leivent wrote:
> I have a data structure that is implemented by a module called "proposal" - part of a distributed agreement protocol.  There is a receive in a separate module that is a gen_server behavior that needs to examine proposals in msgs using API predicates exported from the proposal module.  So, the code would be, if "if" allowed:
> 
> loop(State) ->
>  receive
>    {propose, From, Proposal} ->
>      if proposal:round(Proposal) < State#state.current_round -> ...;
>         proposal:is_subsumed_by(Proposal,
>                                 State#state.last_proposal) -> ...;
> 
> etc.  I'm sure you get the idea.

"Getting the idea" is not the point.
"Seeing the details" is.

> The problem is, once you have multiple conditions that are not guards, and that you want to examine sequentially, what simple structure can you come up with in Erlang?

Well, for one thing, it might be an idea to rip the branching structure
out of the receive.

loop(State) ->
    receive
        {propose, From, Proposal} ->
            handle_proposal(Proposal, State, From)
      ; ...
    end.

handle_proposal(Proposal, State, From) ->
    Proposal_Round = proposal:round(Proposal),
    if Proposal_Round < State#state.current_round ->
          handle_old_proposal(Proposal, State, From)
     ; true ->
          handle_new_proposal(Proposal, State, From)
    end.

handle_new_proposal(Proposal, State, From) ->
    case proposal:is_subsumed_by(Proposal, State#state.last_proposal)
      of true  -> handle_subsumed_proposal(Proposal, State, From)
       ; false -> handle_interesting_proposal(Proposal, State, From)
    end.

And that this point, I stop, because my experience tells me
"BEWARE OF BOOLEANS!"

If the case where Y subsumes X is interesting, how about the
case where X subsumes Y?  Why isn't this something like

    case proposal:relative_generality(Proposal, State#state.last_proposal)
      of identical     ->
       ; more_general  ->
       ; more_specific ->
       ; incomparable  ->
    end

What is common between the various branches?
Could the proposal: module be restructured to provide
additional/alternative queries that make this code
easier to express?

> However, why was that "cond" expression dropped or never fully implemented?

I've often wondered that myself.




More information about the erlang-questions mailing list