I've been having some fun with Elixir. The macro system is really great, and it synergises well with Elixir's pattern matching. You can see it in how they implement unicode support directly in Elixir itself:
https://github.com/elixir-lang/elixir/blob/v1.10.4/lib/elixir/unicode/properties.ex#L271
Basically they load standard unicode.org text files containing data about unicode code points, and then loop over the relevant code points and generate a function clause for each one, all this at compile time.
You can see it in action in the link, in the function do_trim_leading, which removes leading whitespace: the list of whitespace is loaded from lines 275 to 294, and the function clauses are generated on lines 302 to 304. Line 306 contains the clause for when it's not preceded by whitespace.
I looked at the Erlang part of Elixir's source code to figure out how Elixir supports definitions inside for loops, since in theory it seemed like that would require mutable state. It turns out that they basically *do* use mutable state. More specifically, they use ETS ("Erlang Term Storage") to store function definitions during the compilation of a module.