Why is the error on the wrong line?

I'm diving into Chris McCord's Elixir Metaprogramming .

I made a spelling mistake by typing one of the examples:

defmodule Math do
  defmacro say({:+, _, [lhs, rhs]}) do
    qoute do             #spelling mistake (swapped "o" and "u")
      lhs = unquote(lhs) #(CompileError) math.exs:4: undefined function lhs/0
      rhs = unquote(rhs)
      result = lhs + rhs
      IO.puts "#{lhs} plus #{rhs} is #{result}"
      result
    end
  end

  defmacro say({:*, _, [lhs, rhs]}) do
    qoute do #spelling mistake copied
      lhs = unquote(lhs)
      rhs = unquote(rhs)
      result = lhs * rhs
      IO.puts "#{lhs} times #{rhs} is #{result}"
      result
    end
  end
end

      

In a shell, errors make sense:

iex(1)> qoute do: 1 + 2 #spelling mistake
** (RuntimeError) undefined function: qoute/1
iex(1)> unquote do: 1
** (CompileError) iex:1: unquote called outside quote

      

Why does compiling this file give an error on the next line? Is my spelling mistake some valid construct?

The error is shown in the correct file if I delete unquote

.

defmodule Math do
  defmacro say({:+, _, [lhs, rhs]}) do
    qoute do             #function qoute/1 undefined
      result = lhs + rhs
      IO.puts "#{lhs} plus #{rhs} is #{result}"
      result
    end
  end
...

      

Why did the use unquote

carry over the error somewhere else?

+3


source to share


1 answer


This is because as soon as you call it qoute/1

, Elixir assumes it is a function to be defined later and proceeds to compile the code as a function call. However, when we try to compile it, we see unquote, suppose there is a variable defined externally, and everything fails when it is not.



We cannot get around this, because the error occurs when we expand the code and expand quot / unquote the same way.

+3


source







All Articles