Guards! Guards

32 points by hauleth


strongoose

I'm not an elixir programmer, but the thing that's most surprising to me about the last example is that errors in guard expressions cause the guard to be "skipped", instead of propagating to the caller. I think I can see why, but I'm not surprised it leads to counterintuitive results.

jackdk

Ironic, given that Erlang's API design was meant to facilitate intentional programming as described by Armstrong in the Erlang thesis (p109/s4.5). In it, he outlines a set of functions for interrogating a dict so that the programmer's intention is clear (annotations mine):

% Programmer expects key to be present, so raise an error on failure
dict:fetch(Key, Dict) = Val | EXIT

% Programmer expects key to sometimes exist, and to direct control flow based on its presence
dict:search(Key, Dict) = {found, Val} | not_found.

% Programmer only needs to test for the presence of the key
dict:is_key(Key, Dict) = Boolean

Elixir's is_map_key/2 seems to break this by raising if the "dict" argument is not a dict, and exception failures (reasonably, I suppose) cause the entire guard clause to fail. I think an alternative language where or caught exceptions and coalesced them to false would be more surprising in other cases.