17.01.2015 Views

Erlang and OTP in Action.pdf - Synrc

Erlang and OTP in Action.pdf - Synrc

Erlang and OTP in Action.pdf - Synrc

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

48<br />

However, if the first clause doesn’t match, then if the second argument is true, the<br />

second clause of our example will be chosen. But if that clause doesn’t match either, the<br />

third clause is tried, <strong>and</strong> if that still doesn’t match, we’ll get a run-time exception of the type<br />

function_clause to <strong>in</strong>dicate that the arguments didn’t match any of the clauses of the<br />

function <strong>in</strong> this call.<br />

Now, take another look at these clauses <strong>and</strong> th<strong>in</strong>k about what we know at each po<strong>in</strong>t. If<br />

we ever get to the second clause, we know that the first argument is not true (because<br />

otherwise the first clause would match). Likewise, if we get as far as the third clause, we<br />

know that neither of the arguments can be true. The only valid possibility left at that po<strong>in</strong>t<br />

is that both arguments are false (if the function was called with only true or false as<br />

argument values).<br />

It is good programm<strong>in</strong>g practice to make this knowledge explicit <strong>in</strong> the code—that’s why<br />

we don’t accept anyth<strong>in</strong>g else than (false, false) <strong>in</strong> the last clause. It means that if<br />

someone calls this function with some unexpected value like foo or 42, he will get a runtime<br />

exception (function_clause), which is what we want: it means that he will fail early,<br />

so he will get a chance to detect his mistake <strong>and</strong> fix his code as soon as possible, <strong>and</strong> so that<br />

bad data does not propagate further throughout the system. If we had tried to be “nice” <strong>and</strong><br />

said (_, _) <strong>in</strong> the last clause, to just return false <strong>in</strong> all rema<strong>in</strong><strong>in</strong>g cases, then a call such<br />

as either_or_both(foo, bar) would also return false without any h<strong>in</strong>t of a problem.<br />

2.5.3 – Guards<br />

There is still a possibility of some nonsense slipp<strong>in</strong>g through here, though. If someone would<br />

call the above function as either_or_both(true, 42) or as either_or_both(foo,<br />

true), then it would quietly return true as if all was well <strong>in</strong> the world. We can add some<br />

extra requirements to the clauses to plug this hole, us<strong>in</strong>g guards:<br />

either_or_both(true, B) when is_boolean(B) -><br />

true;<br />

either_or_both(A, true) when is_boolean(A) -><br />

true;<br />

either_or_both(false, false) -><br />

false.<br />

A clause guard beg<strong>in</strong>s with the keyword when <strong>and</strong> ends at the -> arrow. It conta<strong>in</strong>s one<br />

or more tests, separated by commas if there are more than one, <strong>and</strong> all of them have to be<br />

true for the clause to be selected. As you can see, we need to use variables <strong>in</strong> the patterns<br />

to be able to refer to them <strong>in</strong> the guard, so we used the names A <strong>and</strong> B here <strong>in</strong>stead of<br />

don’t-care patterns. The is_boolean(…) test is one of those built-<strong>in</strong> functions that you can<br />

call without specify<strong>in</strong>g the module name (they live <strong>in</strong> the erlang module). There are similar<br />

tests for all of the primitive data types: is_atom(…), is_<strong>in</strong>teger(…), etc. The<br />

is_boolean(…) test simply checks that the value is one of the atoms true <strong>and</strong> false.<br />

Apart from such type tests, the number of th<strong>in</strong>gs you can do with<strong>in</strong> a guard is strictly<br />

limited. You can use most of the operators (+, -, *, /, ++, etc.), <strong>and</strong> some of the built-<strong>in</strong><br />

©Mann<strong>in</strong>g Publications Co. Please post comments or corrections to the Author Onl<strong>in</strong>e forum:<br />

http://www.mann<strong>in</strong>g-s<strong>and</strong>box.com/forum.jspaforumID=454

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!