
Thinking About Function Signatures in Elixir - jaxondu
http://rob.conery.io/2015/10/07/thinking-about-function-signatures-in-elixir/
======
eridius
That looks neat. But it also looks to me like your error variant has the wrong
arity.

    
    
      def charge_customer({:error, err}), do: {:error, err}
      def charge_customer({:ok, cart}, card) do
    

The first one takes a single argument {:error, err}, but the second one takes
two arguments, {:ok, cart} and card.

Same issue with the keyword list version, your error function doesn't take a
keyword list at all, just the {:error, err} argument.

~~~
robconery
The first function matches any call to it with an error - this is how
(apparently) you pass error information on to the result. There's no graceful
exit with an error.

The keyword list is pointless with an error function.

~~~
eridius
No it's not.

The error pattern makes it so that if you pass an error to the function, it
just pipes it through and returns the same error. That's different than
throwing an error, which is what happens when you call a function with the
wrong arity.

Which is to say, using the function as defined, if verify_cart() returns
{:error, err}, and I pipe it to charge_customer(card: foo), then instead of
getting the expected {:error, err} value back out, instead a
%FunctionClauseError exception is thrown.

On the other hand, if it were defined as

    
    
      def charge_customer({:error, err}, _), do: {:error, err}
    

then I would get the expected {:error, err} back out.

------
vezzy-fnord
This is, of course, exactly identical to how things work in Erlang, as well. A
lot of conditional logic is done implicitly through polymorphic functions of
the same arity that pattern match on parameters. Proplists are a surprisingly
versatile data structure to exploit.

------
vvanders
Man, cases like this just make me appreciate pattern matching in function
signatures even more.

