What are the dangers of eval in macros, to get the values of an enum symbol

Just to answer your original question, one bug (albeit fixable) is that eval(expr) in a macro evaluates in the module the macro was defined, which is probably not what you wanted.

The core philosophical reason to avoid this is that you generally want to delay evaluation until the code is actually run — and thus macros should just do what they need to in order to spit out the expressions that’ll run later. Muddling what get executed when is just a cause for confusion in many cases.

This case, though, is more comparable to a replacement for a metaprogramming loop like:

for v in instances(Shape)
    fname = Symbol(:intersect_, v)
    @eval $fname(arg) = ...
end

Which, yeah, uses @eval and is perhaps the most idiomatic way to ever use eval. Even if you’re doing this with lots of enums, you can just add another outer for loop. It’s a pretty common pattern that most folks will immediately identify and understand — and Revise.jl can understand it, too! I don’t think the macro-generated definitions are typically Revise-able.

I suppose if you really wanted to use a macro here you could — and then one step better would be to getfield(__module__, enum) to resolve the name in the correct scope instead doing a whole eval.