So far, we have explained how to create macros that return expression objects. Since macros work at the syntax level, they can manipulate code only by examining how it looks. However, Julia is a dynamic system where data types are determined at runtime. For that reason, Julia provides the ability to create generated functions, which allow you to examine data types for a function call and return an expression, just like macros. When an expression is returned, it will be evaluated at the call site.
To understand why generated functions are needed, let's revisit how macros work. Let's say we have created a macro that doubles the value of its arguments. It would look like the following:
macro doubled(ex)
return :( 2 * $(esc(ex)))
end
No matter what expression we pass into this macro, it would just blindly rewrite the code so it doubles the...