[erlang-questions] Nested Case Statements v.s. multiple functions

Nathaniel Waisbrot nathaniel@REDACTED
Mon Sep 25 16:20:03 CEST 2017


More functions is almost always better. You are writing in a functional language. :) I lean towards naming the functions for what they'll do, rather than having an initial arg that tells them what to do: `do_something(Arg)` rather than `do(something, Arg)`.

In your code, it looks like you have a success-path and anything that deviates is an error (a serious one?). I'd begin by writing it:

```
send_update(Request) ->
    {ok, IndexArgs} = check_request(Request),
    {ok, IndexResult} = check_indices(IndexArgs)
    {ok, ValueResult} = get_values(IndexResult)
    ok = transmit(ValueResult).
```

Here, we have a clear description of the happy-path and anything else will crash. If this is a server handling single-shot client requests (a REST server, for example) then you can either silently drop bad clients or have a top-level exception handler that just returns a 4xx or 5xx error. That may be enough right there, but even if you want richer responses to your clients I think the happy-path is a great way to start. The other thing it will do is help you start to think about overall resilience: it's cool if you drop one TCP connection because of an unexpected request, but all your other live connections and the rest of the system ought to be unaffected.



> On Sep 25, 2017, at 9:25 AM, code wiget <codewiget95@REDACTED> wrote:
> 
> Hello everyone,
> 
> As I get further into Erlang, I am starting to realize that some of my functions have been getting pretty ugly with nested case statements. For example, I had a nested case statement that looked something like this:
> 
> Send_update(Arg1) ->
> 	case do this(Arg1) of
> 		{ok, [Val1, Val2]} ->  
> 			case do_that(Val1, Val2) of
> 				{ok, [Val3, Val4]} ->
> 					case do_this2(…) of 
> ….
> 
> It continued into this for another few functions, you get the picture - its ugly, and it is hard to read. 
> 
> So I went and I converted it to a top level function that would then call lower level functions like so:
> 			
> 
> 
> send_update(Arg1) ->  
>     case ... of
>         {ok, [Val1, Val2]} ->  
>             send_update(check_indices, {Arg1, Val1, Val2});
>         Else ->  
>             lager:error("ERROR: ..")
>     end.
> send_update(check_indices, {Arg1, Arg2, Arg3}) ->
>     case check_indices(Arg2, Arg3)of 
>         true ->
>             send_update(get_values, {Arg1, Arg3});
>         false ->
>             lager:error("EMERGENCY: ….")
>     end;
> send_update(get_values, {Arg1, Arg2}) ->
>   ...
>     case ... of  
>         {ok, [Val1, Val2, VAl3]} ->
>             send_update(send_value, {Arg1, Val1, Val2, Val3});
>         Error ->  
>             lager:error("ERROR: …")
>     end;
> send_update(send_value, {Arg1, Arg2, Arg3, Arg4}) ->
>>     Do_something(Args),
>     ok. 
> 
> 
> Now that I look at it though, both don’t look right. They don’t look like something I would write in any other language where I would just have if’s and else’s.
> 
> Is this the proper way to write Erlang? I know everyone has their own style, but I assume there is some accepted form of writing functional programs with deep nests.
> 
> Thank you for your advice!
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list