About 2nd point. def is expecting function call as a first argument. f is treated by Elixir the same as f(), but :f is not a function call (it is just literal atom). If you want to use atom directly then you need to do unquote(:f)() as a function name:
defmodule(M, [{:do, def(unquote(:f)(), [{:do, 9}])}])






















