How to handle nested case

Richard O'Keefe raoknz@REDACTED
Mon Sep 20 02:32:19 CEST 2021


What is wrong with 'try'?

ok({ok,R}) -> R;
ok(E) -> throw(E).

   try
      Server = ok(get_radius_host()),
      Port = ok(get_radius_port()),
      Secret = ok(get_radius_secret),
      {ok,{Server,Port,Secret}}
   catch throw:E ->
      E
   end

WARNING: UNTESTED CODE.

I'd be inclined to do something slightly different:

ok({ok,R}, F) -> F(R);
ok(E) -> E.

   ok(get_radius_server(), fun (Server) ->
   ok(get_radius_host(),    fun (Port) ->
   ok(get_radius_secret(), fun (Secret) ->
      {ok,{Server,Port,Secret}}
   end) end) end)

(which is rather like using >>= \x -> rather than 'do' in Haskell).

I would also be wondering whether it is possible for a non-OK result to be
ambiguous.  Are there values for E that could have come from more than
one of these 'get_*' functions?  Might the caller of your code care about
where the error came from?

I find myself wondering whether a simple
   {ok,Server} = ...
   {ok,Port} = ....
   {ok,Secret} = ...
might not be the most idiomatic "let it crash" Erlang way of all.

There is some important context missing here.
* Why isn't "let it crash" the right answer here?
* Why should the caller be told that an error occurred but
   in a possibly ambiguous way?
* Is there no other validation to be done?
* What do the surrounding comments say?

On Sun, 19 Sept 2021 at 08:50, Gian Lorenzo Meocci <glmeocci@REDACTED> wrote:
>
> Hi,
> I have a function like this:
>
> get_nas_from_conf() ->
> case get_radius_host() of
> {ok, Server} ->
> case get_radius_port() of
> {ok, Port} ->
> case get_radius_secret() of
> {ok, Secret} ->
> {Server, Port, Secret};
> E -> E
> end;
> E ->
> E
> end;
> E ->
> E
> end.
>
> Which is the best way to write this kind of function?
>
> I'd like to have a with operator like in Elixir, to rewrite my function in this way:
>
> get_nas_from_conf() ->
> with {ok, Server} <- get_radius_host(),
> {ok, Port} = get_radius_port(),
> {ok, Secret} = get_radius_secret() ->
> {Server, Port, Secret};
> catch
> {error, _Reason} = E ->
> E
> end.
>
> Any suggestion?
>
> --
> GL
> https://www.meocci.it


More information about the erlang-questions mailing list