This does only explain it roughly, but should be just enough to understand it.
Kernel.to_string/1is a macro, expanding toString.Chars.to_string/1String.Chars.to_string/1matches on its argument, and without protocol consolidation it dispatches toString.Chars.xxx.to_string/1wherexxxis the qualified alias of the struct or elixirs internal type. With consolidation thosexxximplementations are integrated directly intoString.Chars.to_string/1.
With consolidation it might look like this (simplified):
defmodule String.Chars do
def to_string(list) when is_list(list), do: List.to_string(list)
def to_string(%Foo{bar: bar}), do: "#Foo<bar: #{bar}>"
end
without consilidation more like this:
defmodule String.Chars do
def to_string(list) when is_list(list), do: List.to_string(list)
def to_string(%struct{} = item), do: :"Elixir.#{__MODULE__}.#{struct}" |> apply(:to_string, [item])
end






















