Tentatively writing a generated function and relearning things, and ran into a couple questions:
- The most warned limitation of generated functions is most side effects in the method body (throwing errors is a notable exception). The docs currently words the rationale:
The number of times a generated function is generated might be only once, but it might also be more often, or appear to not happen at all. As a consequence, you should never write a generated function with side effects - when, and how often, the side effects occur is undefined. (This is true for macros too - and just like for macros, the use of
evalin a generated function is a sign that you’re doing something the wrong way.)
I never noticed the mention of macros there. Macro calls are documented to execute when called at parse-time, with no mention of caching like generated functions, so are side effects in macro bodies really undefined behavior? I wouldn’t want macro calls to depend on global state or anything, but the documented parse-time println examples with no warnings seem to contradict that.
- I never fully understood why a generated function’s method is stuck in the world age during definition, e.g. callees only use prior defined methods. Issue #23223 suggests to me that the core reason is the method’s execution being part of compile-time, but normal functions can opt to execute callees at compile-time without being stuck in a world age. In fact, my primary consideration now is a semantic guarantee of compile-time computation, no side-effects of course. Is the generated expression stuck per
MethodInstancesomehow? Hypothetically, if there were a@compiletimehint in normal functions e.g.foo(x::T, ::Val{N}) where {T, N} = x + @compiletime(bar(T, N))to do what I intend, would that somehow avoid the limitations of generated functions except for side effects?