Macros help

I wonder why this is

iex(5)> q = quote do
...(5)>   p.location_id == ^location_id and l.id == p.location_id and l.deleted != true
...(5)> end

Macro.to_string(q)
"p.location_id() == ^location_id and l.id() == p.location_id() and l.deleted() != true"

IOW why p.location_id() ?

According to the Documentation, the . operator can do two things:

  1. Create an Alias. These are constructs like Foo.Bar. This is done when both operands are symbols that start with a capital letter.

  2. Perform a call to a remote function. Here, the left-hand-side argument to . is the module, and the right-hand-side argument is the function name to call.

In your example, the second case happens. This is why you end up with the extra parentheses. For calling a zero-arity function, parentheses are optional (but many people like to add them to make it more explicit what is going on). Underwater, the elements of a struct are simply functions that are called on the secretly defined struct module, which will return the appropriate element from the underlying map.

So, Tl;Dr: You see p.location_id() because, as Elixir’s parser can infer from the ., location_id is a function.