Stream: helpdesk (published)

Topic: Which variable needs to be escaped in quoted expression


view this post on Zulip Simon Schoelly (Feb 17 2021 at 20:10):

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})

view this post on Zulip Felix Kastner (Feb 17 2021 at 20:42):

Are you missing a colon after n?

view this post on Zulip Mason Protter (Feb 17 2021 at 20:56):

You shouldn't have to escape anything in a generated function.

view this post on Zulip Mason Protter (Feb 17 2021 at 21:00):

What is the code Vector{Vector{T}}(n) meant to do? That's undefined.

view this post on Zulip Mason Protter (Feb 17 2021 at 21:03):

Putting println statements in there shows me that n is actually a DataType 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

view this post on Zulip Simon Schoelly (Feb 17 2021 at 21:55):

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

view this post on Zulip Mason Protter (Feb 17 2021 at 22:03):

Ah, I see yes. You need to interpolate (different from escape) T because it’s defined inside the generator.

view this post on Zulip Mason Protter (Feb 17 2021 at 22:03):

Only the function arguments can stay as symbols in the returned expression.


Last updated: Oct 02 2023 at 04:34 UTC