I have an generated function like this:
@generated function f2(n:Int, ::Type{E_VALS}) where E_VALS
args = []
for T in fieldtypes(E_VALS)
push!(args, :(Vector{Vector{$T}}(n)))
end
return Expr(:call, :tuple, args...)
end
For some reason this function will not work if I do not escape T
nor if I escape n
. Is there any difference in them? Putting println
statements in there shows me that n
is actually a DataType
which is a bit weird. I called the method with f2(10, Tuple{Int, Char})
Are you missing a colon after n?
You shouldn't have to escape anything in a generated function.
What is the code Vector{Vector{T}}(n)
meant to do? That's undefined.
Putting
println
statements in there shows me thatn
is actually aDataType
which is a bit weird
All function arguments are types inside a generated function body.
julia> @generated function f(x)
Core.println("Inside the generated function body, x = $x")
:(println("at runtime, x = $x"))
end
f (generic function with 1 method)
julia> f(1)
Inside the generated function body, x = Int64
at runtime, x = 1
julia> f(1)
at runtime, x = 1
julia> f(2)
at runtime, x = 2
Apparently I made at least two mistakes when I copied this function here, the function actually is:
@generated function f2(n::Int, ::Type{E_VALS}) where E_VALS
args = []
for T in fieldtypes(E_VALS)
push!(args, :(Vector{Vector{$T}}(undef, n)))
end
return Expr(:call, :tuple, args...)
end
so if I remove the dollar sign from T
and try to run it, I get an error message
julia> f2(2, Tuple{Int, String})
ERROR: UndefVarError: T not defined
Stacktrace:
[1] macro expansion
@ ./REPL[45]:0 [inlined]
[2] f2(n::Int64, #unused#::Type{Tuple{Int64, String}})
@ Main ./REPL[45]:1
[3] top-level scope
@ REPL[46]:1
Ah, I see yes. You need to interpolate (different from escape) T
because it’s defined inside the generator.
Only the function arguments can stay as symbols in the returned expression.
Last updated: Dec 28 2024 at 04:38 UTC