Tuple Calls

Tuple calls are slated to be turned into an error in Elixir 2 Jose keeps saying he wants to do.

Technically it is for a good reason, the BEAM error messages when someone tries a tuple call accidentally on a module that is not tuple-callable is a bit ugly, but the feature is just so fantastically useful, it is basically first-class modules on the BEAM and that opens up so many possibilities that would be so very wordy otherwise!

Someone can accidentally do a tuple call, say, like this:

iex(12)> m = %{a: %{b: 42}}
%{a: %{b: 42}}
iex(13)> blah = Map.fetch(m, :a)
{:ok, %{b: 42}}
iex(14)> blah.b
** (UndefinedFunctionError) function :ok.b/1 is undefined (module :ok is not available)
    :ok.b({:ok, %{b: 42}})

What the user probably meant to do was this for the fetch line instead:

iex(13)> {:ok, blah} = Map.fetch(m, :a)

And this is a common bug caused by the lack of a typing system in Elixir (thus the compiler cannot catch it, although Dialyzer can, but how many people, especially newbies, use Dialyzer? I really think Dialyzer should run ‘with’ the compiler, and be optimized/PLT’d as much as possible with auto-updating of the PLT as necessary).

So yes, tuple calls are amazingly wonderful and I love them (I’m a long time erlang fan of tuple-calls), but they do make for some… interesting error messages when someone did not intend to use them (Newbie says: “Wtf? :ok.b/1? Wtf?”).

7 Likes