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

Krzysztof Jurewicz krzysztof.jurewicz@REDACTED
Wed Sep 27 13:16:13 CEST 2017


Richard A. O'Keefe writes:

> 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. […]
>
> The thing is that error *detection* does have to be done often,
> but error *handling* should be rare.

The problem with such cases is that they involve dealing with user-provided input, which can be arbitrary and system makers have no control over it. An user is free to submit a request trying to purchase an equipment without having sufficient balance, and the server is supposed to inform him that he cannot do it. In HTTP terminology, it is a 4xx error, not a 5xx error, and there is no failure on the server side. Therefore there is a natural resistance for using throw/1 in such cases.

In Haskell, the staircasing problem could be solved using monads, though one may argue that what they actually do is hiding the staircase, not getting rid of it (see the comments at http://book.realworldhaskell.org/read/code-case-study-parsing-a-binary-data-format.html#PNM.hs:parseP5_take2 ). I understand that with the absence of such constructs in Erlang throw/catch is advised as a workaround. Actually the documentation of throw/1 names it “a non-local return from a function” and doesn’t mention errors at all. Then we however come to a conviction common in other languages that using exceptions for flow control is a bad idea…



More information about the erlang-questions mailing list