I think that the metaprogramming situation is a little problematic in Elixir. Elixir makes heavy use of macros in basic libraries like the Phoenix or Ecto frameworks that are used by more or less everybody.

I understand that macros are useful to build a DSL for a specific project but using macros in basic libraries like this leads to "way too much magic": Trying to understand (or somehow extend) Ecto is not really possible for all practical purposes and following the control flow in Phoenix is like a maze because of all the macro substitutions. This also leads to cryptic errors where you get an error in non existant lines of code.

This heavy of macros is my main complain about Elixir and I think it's one of the main problems that new people face when trying the language resulting in either not using it at all (or if they start it they will abandon it).

Finally, I understand that using macros in these libs allows for much more compact (and maybe beautiful) code, however I will always pick a more verbose (but less magic) version of this if I had the choice. I think this is the case for most programmers that want to use a language as a tool to do their job.

Macros can be de-mystified with proper editor support. In Emacs and Lisp you can (recursively) use "macroexpand" to see what code it produces in-place. I am not an Elixir user (though thinking about hopping on), apparently there is alchemist.el[1] that lets you do that (with caveat, and the project seems dead tbh).

[1] https://github.com/tonini/alchemist.el

Macro expansion has recently been added to elixir-ls[1] and is supported via custom command in vscode extension.

[1] https://github.com/elixir-lsp/elixir-ls