5

Does "for" always checks the type of first argument in each function defined in a protocol?

EDIT (rephrasing): When protocol method has only one argument, implementation is found based on the type of this single argument (either direct or as Any). When protocol method has multiple arguments, which one is used to find the corresponding implementation? Is it always the first one? Can it be changed?

2 Answers2

8

The implementation is always determined based on the first argument.

When you define a protocol, a generic protocol module will be generated. All def clauses in that module will perform delegations to concrete functions, determining which function to call based on the type of the first argument.

The place in Elixir source where this happens is here (where first argument is explicitly referred to as t), and here (where t is passed to impl_for! to obtain the module where the function call is forwarded).

A defimpl will generate concrete modules whose names adhere to the internal conventions used by defprotocol. Thus it is ensured that function call will be delegated to the proper concrete module.

sasajuric
  • 5,949
  • 1
  • 22
  • 18
0

It's my understanding that for defines what type the protocol implementation is for. When a function specified in a protocol is invoked on a value, Elixir checks to see if there is an implementation of that function for that type. Of course there are some special cases like fallback to Any and built in protocols. But to answer your question, yes, as far as I know, the type is always checked.

More can be learned by inspect the source code:

https://github.com/elixir-lang/elixir/blob/150a8a1dcd3610d5ff875e00a1c8779894456ca6/lib/elixir/lib/protocol.ex#L522 https://github.com/elixir-lang/elixir/blob/150a8a1dcd3610d5ff875e00a1c8779894456ca6/lib/elixir/lib/protocol.ex#L456

EDIT

It appears that the type of the first argument is the only thing that matters.

Starting on line 28 in protocol.ex, it seems that the first argument is the only one that is taken into account: https://github.com/elixir-lang/elixir/blob/150a8a1dcd3610d5ff875e00a1c8779894456ca6/lib/elixir/lib/protocol.ex#L28

From what I understand only the type of first argument is taken into account. The types of all the other values are ignored.

Stratus3D
  • 4,648
  • 4
  • 35
  • 67