Beautiful Erlang - Validating Function Arguments

February 1, 2011


Validating the arguments of an Erlang function can lead to severely nested code. Let’s say we have two different functions that must be called to validate our data, and we want to throw a different exception depending on which one fails. One possible way to code this is:

my_funtion(Data) ->
    case is_valid_A(Data) of
        true ->
            case is_valid_B(Data) of
                true ->
                    ...function body...
                false ->
                    throw({error, validator_B_failed})
            end;
        false ->
            throw({error, validator_A_failed})
    end.

This is ugly for a few reasons:

A better option is to use the ‘orelse’ operator to throw the exception if something fails. We can rewrite the above code as follows:

my_funtion(Data) ->
    is_valid_A(Data) orelse throw({error, validator_A_failed}),

    is_valid_B(Data) orelse throw({error, validator_B_failed}),

    ... function body ...

This works because the orelse operator is short-circuiting. The system evaluates the first clause. If the result is true, then no other statements are evaluated. If the result is false, then the system evaluates the next clause, which throws our exception.

By structuring the code like this we save a lot of typing, make the intentions of the code clearer, provide an easy pattern for adding future validations if necessary, and make it easy to comment out validators quickly.

Back


Content © 2006-2021 Rusty Klophaus