Erlang equivalent to if else

46,151

Solution 1

The form for an if is:

if
    <guard 1> -> <body1> ;
    <guard 2> -> <body2> ;
    ...
end

It works trying the guards in if-clauses in top-down order (this is defined) until it reaches a test which succeeds, then the body of that clause is evaluated and the if expression returns the value of the last expression in the body. So the else bit in other languages is baked into it. If none of the guards succeeds then an if_clause error is generated. A common catch-all guard is just true which always succeeds, but a catch-all can be anything which is true.

The form for a case is:

case <expr> of
    <pat 1> -> <body1> ;
    <pat 2> -> <body2> ;
    ...
end

It works by first evaluating and then trying to match that value with patterns in the case-clauses in op-down order (this is defined) until one matches, then the body of that clause is evaluated and the case expression returns the value last expression in the body. If no pattern matches then a case_clause error is generated.

Note that if and case are both expressions (everything is an expression) so they both must return values. That is one reason why there is no default value if nothing succeeds/matches. Also to force you to cover all options; this is especially important for case. if is just a degenerate case of case so it inherited it. There is a bit of history of if in the Erlang Rationale which you can find on trapexit.org under user contributions.

Solution 2

Erlang doesn't allow you to have an if without a true statement option. Whether or not this is something that is a true statement or an actual true is up to you, but it is commonplace to have your true be the else in other languages.

if 
    some_condition -> some_code;
    some_other_condition -> some_other_code;
    true -> else_code
end.

See the "What the If?" section on this page for more on this.

Solution 3

Remember if in Erlang has a value to return, and it's an expression. It's not that if like in C or Java.

If you want to do something for a value, the code should be something like this;

if
  % do something and get the value
  X >= Val -> Something;
  % for doing something otherwise and get the value
  true -> Else_than_the_Something 
end.

See Section for the if expression of Erlang Reference Manual for the further details.

Solution 4

First of all, I recommend you to get used to use 'case' statement, because of 'if' conditions restricted to guard expressions:

case custom_call(A) of
  1 -> do1(A);
  2 -> do2(A)
end.

There is one more way to do conditional execution besides 'if' and 'case' that works starting from R13:

  1> N =10.
  10
  2> ((N > 10) andalso more).      
  false
  3> ((N == 10) andalso equals).
  equals
Share:
46,151

Related videos on Youtube

some_id
Author by

some_id

Updated on July 09, 2022

Comments

  • some_id
    some_id almost 2 years

    I have 2 parts of code I want to execute. Both are conditionals

    if Value1 < N do something 
    
    else if Value1 >= N do something
    
    if Value2 < N do something 
    
    else if Value2 >= N do something
    

    I want at one statement of each to execute.

    How does the if work in erlang? there is no else. I use multiple guards, but that looks like I have 4 if statements. in groups of 2.

    if some condition   
    code;
    
    if other condition  
    code
    
    end.
    

    I get a syntax error.

  • Alexey Romanov
    Alexey Romanov over 13 years
    It certainly does allow to have an if without a true branch, and will throw an exception at run-time in this case.
  • Reese Moore
    Reese Moore over 13 years
    Hence, "erlang doesn't allow toy to have an if without a true statement option.". If nothing evaluates to true you are going to get an exception.
  • I GIVE TERRIBLE ADVICE
    I GIVE TERRIBLE ADVICE over 13 years
    But getting an exception IS good. It means one case didn't go through what you planned. It could be argued that catching all 'else' clauses is as bad as catching all exceptions blindly: if X > 0 -> ...; X < 0 -> ...; X =:= 0 -> ... end. Is more explicit and safe than using 'true' for the last clause.
  • some_id
    some_id over 13 years
    If I use a case, wont it exit when it matches to some case? Or will it execute that case and move on to try match the second?
  • I GIVE TERRIBLE ADVICE
    I GIVE TERRIBLE ADVICE over 13 years
    There is no reason to blindly use case ... of ... end instead of if. If your check can be limited to guards, use 'if'. Otherwise you're uselessly complicating your code with empty match clauses in a 'case'.
  • some_id
    some_id over 13 years
    Ok, But my question remains. Will the code exit the if statements if it executes one? Or will it execute the statement and move onto the next guard? I need some code to execute depending on the value. and then I have another method which should do the same depending on a another value. First if is Value >= queue:len and the else should be Value < queue:len . So two if else statements.
  • Reese Moore
    Reese Moore over 13 years
    True, but what if you want to test for (math syntax, not haskell) 4<x<7, 1<x<2, -10<x<-7, x>=20, x<-100 to do specific things in each case, and in any other case do something else (a contrived example, maybe). Sure -100 <= x <= -10 or -7 <= x <= 1 or 2 <= x <= 4 or 7 <= x < 20 might be more explicit, but a true (or an else in another language) is faster to write and less error prone.
  • I GIVE TERRIBLE ADVICE
    I GIVE TERRIBLE ADVICE over 13 years
    It is less error prone when writing it (in appearance), not when using it. If you did make a mistake in your clauses, the error will be hidden until your data is corrupt somewhere else. Having it explicit takes longer, but is generally safer and easier to understand when reading it later on. See the link you posted, near the bottom, the quote from Richard O'Keefe.
  • I GIVE TERRIBLE ADVICE
    I GIVE TERRIBLE ADVICE over 13 years
    With an if or case, it will match the first one, execute it and then leave. Only if it doesn't match the first branch will it try the second, third, etc. This is not like a 'case' or 'switch' with fall-through clauses as in C.
  • some_id
    some_id over 13 years
    Ok thanks. So it will work to have the first "if else" in a case and then the next "If else" in a second case. I need the one to finish by executing one of the 2 and then move on to the next part and execute one of the 2.
  • I GIVE TERRIBLE ADVICE
    I GIVE TERRIBLE ADVICE over 13 years
    Try it and see, it will be shorter ;)
  • Admin
    Admin about 5 years
    How do I find the reference "There is a bit of history of if in the Erlang Rationale which you can find on trapexit.org under user contributions."?

Related