[erlang-questions] Nested Case Statements v.s. multiple functions
dploop@REDACTED
dploop@REDACTED
Tue Sep 26 04:40:28 CEST 2017
This problem also bothered me for a long time, so I write a parse transform to deal with it. To be specific, say we want to write a function which takes two integers and returns the product and quotient of them.
muldiv(First, Second) ->
case is_integer(First) of
true ->
case is_integer(Second) of
true ->
Product = First * Second,
case Second =/= 0 of
true ->
Quotient = First div Second,
{ok, {Product, Quotient}};
false ->
{error, "Second must not be zero!"}
end;
false ->
{error, "Second must be an integer!"}
end;
false ->
{error, "First must be an integer!"}
end.
Ugly, at least I think this "rocket" is not beautiful. Even worse, if requirement changed, you should modify this code on a large scale. To avoid this problem, you can just rewrite your code like this
muldiv(First, Second) ->
do@([esugar_do_transform_error ||
case is_integer(First) of
true -> return(next);
false -> fail("First must be an integer!")
end,
case is_integer(Second) of
true -> return(next);
false -> fail("Second must be an integer!")
end,
Product = First * Second,
case Second =/= 0 of
true -> return(next);
false -> fail("Second must not be zero!")
end,
Quotient = First div Second,
return({Product, Quotient})
]).
This idea came from the Haskell's do grammer, and to use this grammer, you just need to write a error monad.
This parse transform code is one module of my esugar(An Erlang Syntactic Sugar Library) library, and the address is (https://github.com/dploop/esugar)
I'm glad to discuss with you about how to use it or improve it(because I just write this toy for fun at the begining).
dploop@REDACTED
From: code wiget
Date: 2017-09-25 21:25
To: Erlang-Questions Questions
Subject: [erlang-questions] Nested Case Statements v.s. multiple functions
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170926/89ff8fc8/attachment.htm>
More information about the erlang-questions
mailing list