I found that @fastmath
has some problems with Base.Cartesian.@nexprs
, like so:
julia> Base.@nexprs 5 j -> y_j = rand()
0.13646394987531396
julia> @fastmath Base.@nexprs 4 j -> x_j = y_{j + 1}
ERROR: UndefVarError: `y_` not defined in `Main`
Suggestion: check for spelling errors or missing imports.
Stacktrace:
[1] top-level scope
@ REPL[2]:1
julia> @macroexpand @fastmath Base.@nexprs 4 j -> x_j = y_{j + 1}
quote
x_1 = y_{Base.FastMath.add_fast(1, 1)}
x_2 = y_{Base.FastMath.add_fast(2, 1)}
x_3 = y_{Base.FastMath.add_fast(3, 1)}
x_4 = y_{Base.FastMath.add_fast(4, 1)}
end
julia> @macroexpand Base.@nexprs 4 j -> x_j = y_{j + 1}
quote
x_1 = y_2
x_2 = y_3
x_3 = y_4
x_4 = y_5
end
It looks like it's basically @fastmath(@nexprs(4, ...))
, so evaluating from inside to outside, shouldn't @fastmath
just enable fastmath for the whole block after getting the output from the @nexprs
macro? Or does macro evaluation follow a different order, like from outside in?
Yes, macros evaluate outside in, because they operate on chunks of code.
Can I sort of make them evaluate inside out?
Or achieve that kind of effect, basically.
yes, you just have to make the outer macro look for macros inside of it and then macroexpand
them
I suppose the most general way would be to define a separate macro @expandafter
that rewrites
@expandafter @outer @inner expr
to
@outer inner_expr_expanded
In TeX, which is a pure macro expansion language, this macro is built in.
https://jkrumbiegel.com/pages/2022-08-09-composing-macros/
Last updated: Oct 18 2025 at 04:39 UTC