[erlang-questions] if-elseif-else trick

Dmitry Kolesnikov dmkolesnikov@REDACTED
Tue Feb 19 10:51:24 CET 2019


Hello Viktor,

You might look into my solution where this concept is generally solved under the abstraction of category pattern.

https://github.com/fogfish/datum/blob/master/doc/category.md


Best Regards,
Dmitry


> On 19 Feb 2019, at 11.48, Peti Gömöri <gomoripeti@REDACTED> wrote:
> 
> This makes much more sense now :) Just noting that Elixir has the `cond` expression for this use case.
> 
> On Tue, Feb 19, 2019 at 8:37 AM Viktor Söderqvist <viktor@REDACTED <mailto:viktor@REDACTED>> wrote:
> Hi!
> 
> My example proved silly. Of course, normal 'if' is fine for guard
> expressions and catch-all is to be avoided in general. I agree.
> 
> What I failed to mention was that you can use non-guard expressions with
> this trick. (The trick's actually rewriting the elseifs to nested case.)
> 
> When using if with non-guard expressions, you need to evaluate them in
> advance, which you may not want if these are side-effectful or just slow:
> 
> f() ->
>     Cond1 = g1(),
>     Cond2 = g2(),
>     Cond3 = g3(),
>     if Cond1 -> a;
>        Cond2 -> b;
>        Cond3 -> c;
>        true  -> d
>     end.
> 
> Therefore, you often see nested case expressions instead:
> 
> f() ->
>     case g1() of
>         true -> a;
>         false ->
>             case g2() of
>                 true -> b;
>                 false ->
>                     case g3() of
>                         true -> c;
>                         false -> d
>                     end
>             end
>     end.
> 
> ... or broken down into multiple functions:
> 
> f() ->
>     case g1() of
>         true -> a;
>         false -> f2()
>     end.
> f2() ->
>     %% You know
> 
> There's the throw style too, a slightly silly but a flat style:
> 
> f() ->
>     try
>         g1() andalso throw(a);
>         g2() andalso throw(b);
>         g3() andalso throw(c);
>         d
>     catch
>         X -> X
>     end.
> 
> The point of the ?elseif syntax trick is that it lets you write the
> nested case above as the flat structure:
> 
> f() ->
>     ?'if'(g1())   -> a;
>     ?elseif(g2()) -> b;
>     ?elseif(g3()) -> c;
>     ?else         -> d.
> 
> You can even bind variables in the conditions if you would want that,
> just to avoid deeply nested code. I would look more like perl than
> erlang though, so don't do that.
> 
> >> That said...
> >> The original premise of this thread is based on a misunderstanding of `if` and probably inexperience with `case`.
> > 
> > Agreed
> > 
> 
> I agree too. :-) Thanks for clarifying!
> 
> Btw, I'm sorry for posting without having a real question. I just wanted
> to show what can be done using a non-trivial parse transform.
> 
> Viktor
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED <mailto:erlang-questions@REDACTED>
> http://erlang.org/mailman/listinfo/erlang-questions <http://erlang.org/mailman/listinfo/erlang-questions>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20190219/c1837c92/attachment.htm>


More information about the erlang-questions mailing list