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

Richard A. O'Keefe <>
Wed Sep 27 07:39:26 CEST 2017



On 26/09/17 6:16 PM, dploop wrote:
> is_integer, is_zero is just a simplified example, and by coincidence,
> they can use in the guard. But in most situations you can't use guard,
> for example in game industry when player want to buy equipment, you
> should check if his coin is sufficient, and then you should check the
> number of equipment is right and then you  should check if the equipment
> is valid to exchange and so on. The complex business logic can't be
> easily solved by guard, and Nested Cases is inevitable.

Actually, no.  My example shows that something like
     try
         must_be:at_least(Coin, Price),
         must_be:at_least(Equipment, Required),
         must_be:exchangeable(Equipment),
         New_State = exchange(Equipment, Old_State),
         {ok, New_State}
     catch
         throw:Reason -> {error,Reason}
     end
is perfectly possible.  Indeed, idiomatic Erlang would be

     true = enough_coin(Player, State, Purchase),
     true = equipment_amount_right(State, Purchase),
     true = is_exchangeable(State, Purchase),
     exchange(Equipment, State)

The thing is that error *detection* does have to be done often,
but error *handling* should be rare.

Alternatively, you could have a convention that a function
whose name begins with 'check_' either returns a useful
result, or the trivial result (ok), or throws, and write

     check_enough_coin(...),
     check_equipment_amount_right(...),
     check_is_exchangeable(...),
     exchange(...)

Then you can have a general purpose wrapper

catch_check(Fun) ->
     try
         {ok, Fun()}
     catch
         throw:Reason -> {error,Reason}
     end.

and write

     catch_check(fun () ->
         check_...
         check_...
         check_...
         exchange(...)
     end)

There are many ways to kill this particular cat,
but stuffing it with Nested Cases is not a good one.


More information about the erlang-questions mailing list