<br><br><div class="gmail_quote">On Tue Dec 16 2014 at 5:07:22 PM Alex Wilson <<a href="mailto:alex@cooperi.net">alex@cooperi.net</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
> On 17 Dec 2014, at 10:31 am, aman mangal <<a href="mailto:mangalaman93@gmail.com" target="_blank">mangalaman93@gmail.com</a>> wrote:<br>
><br>
> > Moreover, is there a good alternate to avoid nested case statements?<br></blockquote><div><br></div><div>I think everybody would agree that there is a smell that comes from nested case expressions, which shows up in the fact that idiomatic Erlang tends toward lots of short functions.  It's kind of a non-answer, but I would say replace a nested case with a function call.</div><div><br></div><div>I personally find that unlike in a language like C where having a ton of functions can sometimes make things a little muddled, after working with Erlang for a while matching inside a case and calling functions (which generally means having a lot of functions) on the result is very natural, and actually makes your code easier to follow, debug, and test.  </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
><br>
<br>
You could consider something like a monad, perhaps. I know "monad" is a horrible functional programming word that makes people go "OMG THAT'S TOO HARD", but it's a pretty clean way to deal with errors sometimes.<br>
<br>
<a href="https://github.com/rabbitmq/erlando#do" target="_blank">https://github.com/rabbitmq/<u></u>erlando#do</a> has an example of implementing do-notation for monads in Erlang using a parse-transform. The error monad example is kind of interesting.<br>
<br>
You can do the same thing without the parse-transform by having a function like this one:<br>
<br>
threaduntil([], Acc) -> Acc;<br>
threaduntil([Fun | Rest], Acc) -><br>
        case Fun(Acc) of<br>
                {error, E} -> {error, E};<br>
                Acc1 -> threaduntil(Rest, Acc1)<br>
        end.<br>
<br>
So you call this with a list of funs, and whatever the output from one fun is, becomes the argument to the next one on the list, until either it reaches the end of the list (and returns the last return value), or one of the funs returns {error, _} -- then it short-circuits and returns the error straight away.<br>
<br>
It's not the lowest-overhead thing ever (making all those funs and executing them), but usually you see this kind of thing when dealing with i/o or high-level control logic that doesn't have to be the fastest-executing thing ever.<br>
<br>
I've used this pattern (and the erlando do-transform specifically) quite a lot to avoid chains of Thing1 = blah(Thing), Thing2 = foo(Thing1), Thing3 = bar(Thing2)... etc etc, and also to deal with situations where deeply nested errors need to produce a well-defined return value. I have a personal distaste for try/catch, so I prefer to choose between either crashing the process, or using this kind of approach.<br>
<br>
______________________________<u></u>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/<u></u>listinfo/erlang-questions</a><br>
</blockquote></div>