When I started writing macros that define named functions with def
, I didn’t find any blog posts etc. that were devoted to the topic. Are there any? Should I write one? There are, I think, some special gotchas that beginners should be able to find all in one place.
I’m referring to macros like one I recently wrote:
defmacro defaults_may_be_overridden(pairs) when is_list(pairs) do
for pair <- pairs, do: Here.def_optional(pair)
end
def def_optional({name_atom, default}) do
function_name = {name_atom, [], nil}
quote do
def unquote(function_name),
do: get_env(unquote(name_atom), unquote(default))
end
end
That’s used to create a bunch of configuration getters functions while omitting unnecessary words:
defaults_may_be_overridden(
reload_timeout: 150,
logging_enabled: true,
reload_callback: constantly(:irrelevant_return_value),
load_first: false,
src_dirs: []
)
There are issues like:
-
defmacrop
may surprise you because it doesn’t create macros available at function-definition scope. - Converting between function name ASTs and atoms is something you have to learn.
- If you want to write a
defXXX
macro, you may want to handle guards, and the AST for guards was surprising to me.