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

Jonathan Leivent jleivent@REDACTED
Fri Jun 21 02:34:43 CEST 2013

On 06/20/2013 07:01 PM, Richard A. O'Keefe wrote:
> On 21/06/2013, at 3:29 AM, Jonathan Leivent wrote:
>>         ?ELSE
>>             expr0,
>>             expra,
>>             ?BREAK(exprb),
>>         ?ENDIF.
> The ?BREAK is rather horrible; to my mind, far more horrible than nice
> clean obvious closures.

I never claimed it was a good solution.  Rather, it's the lack of an 
unrestricted sequential multi-conditional statement that made me 
consider such things.

> I wrote:
>>> However, I cannot help feeling that in each specific instance
>>> of this there would be something better to write instead.  So
>>> how about showing us a real example?
>> Anything that would have worked in an if statement were the conditions just guards.  In the case I'm interested in, the conditions are predicates on an opaque type - so they can't be guards.
> That's interesting, but I doubt that anyone ever thought
> you _could_ have written your code as a simple 'if'.
> *How about showing us a real example?*
> As in, actual code.

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) ->
     {propose, From, Proposal} ->
       if proposal:round(Proposal) < State#state.current_round -> ...;
                                  State#state.last_proposal) -> ...;

etc.  I'm sure you get the idea.

> Real examples often show opportunities for restructuring in
> completely different ways.

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?

> Also, I'm having a hard time imagining so many sequentially
> tested conditions that
> 	case C1
> 	  of true -> A1
>             ; false ->
> 	     case C2
>                 of true -> A2
>                  ; false ->
> 		   ...
>               end
> 	end
> is really hard to write.  It's certainly what
> cond C1 -> A1 ; C2 -> C2 ; ... end
> would compile into, if it existed.

Oh - certainly - there's only 4 in my current case, but as the design 
expands, there could easily be more.  But, 4 is plenty already ugly 

I'm probably only doing a mediocre job of justifying an if/elsif/else 

>>> Because back when Erlang was invented, there were no conditions that
>>> were not guard tests *only*.  For example, X > Y was not an expression.
>>> There were no andalso or orelse.
>> OK - I will then add a word to the above question: why does Erlang *still* require the conditions in an if statement to be guards?
>> How hard is it to remove this restriction?
> Expressions and guards have radically different semantics.
> It was a really bad mistake when people started making them
> look more similar.
> For example, tuple_size(T) div N =:= M doesn't raise an
> exception when N is zero, it just *fails*.
> Guards are part of pattern matching; in order to get efficient
> pattern matching code it is important that the compiler should
> be free to reorder matching and testing any way it likes; in
> particular  G1, G2  need not be tested in the order G1 then G2
> and often shouldn't be tested in that order.  But if these
> could be called to user defined functions, such reordering
> could break things.
> It would probably be easier to design a new Erlang-like language
> compiling to the same VM than to *coherently* unify guards and
> expressions.

OK - now that I understand how different guards are, I would not at all 
suggest that if statements should be modified to allow normal 
conditional expressions.

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

-- Jonathan

More information about the erlang-questions mailing list