elixir

Why Isn't This Function Called "Left"?


Ok, I really feel dumb for having to ask this but I’m very curious.

In Jose’s 2023 keynote he showed this example of why the new type implementation won’t prevent certain bugs:

def left and right do
  Enum.random([left, right])
end

So just to see if he was just making something up to make his point I tried it in iex and sure enough–there’s an and function. What puzzles me is how is it that left isn’t the name of the function? How is it possible to have arguments before and after the name of the function?


Solution

  • In , everything is a macro. Kernel.def/2 is no exception. Macros receive AST of its params rather than params themselves. This is what actually receives Kernel.def/2 (I simplified the block for the sake of clarity)

    iex|💧|1 ▶ quote do
    ...|💧|1 ▶   left and right do
    ...|💧|1 ▶     :ok
    ...|💧|1 ▶   end
    ...|💧|1 ▶ end
    {:and, [context: Elixir, imports: [{2, M}]],
     [{:left, [], Elixir}, {:right, [], [[do: :ok]]}]}
    

    That said, this is the duty of Kernel.def/2 macro to feature infix “operators” in .

    For the further reference, one should dig into :elixir_def codebase.