How do I concatenate symbols containing curly brackets into a single symbol?

I’d like to obtain the code

struct S{𝒯<:Real}
end

programmatically. Method 1 below works, but I’d like to be able to feed in the variable name (here S) automatically (e.g. by passing a variable x containing :S) and hence to construct a single symbol out of the concatenation of x and {𝒯<:Real}. How do I accomplish this? The curlies appear to be the culprit here; see methods 2 through 4 below.

name₁ = :(S₁{𝒯<:Real})
name₂ = Symbol( :S₂, :({𝒯<:Real}) )
name₃ = Symbol( :S₃, :T )
name₄ = Symbol( "S₄{𝒯<:Real}" )

e₁ = Expr( :struct, false, name₁, Expr( :block ) )
e₂ = Expr( :struct, false, name₂, Expr( :block ) )
e₃ = Expr( :struct, false, name₃, Expr( :block ) )
e₄ = Expr( :struct, false, name₄, Expr( :block ) )

eval( e₁ )
eval( e₂ )
eval( e₃ )
eval( e₄ )


dump( e₁ )
dump( e₂ )
dump( e₃ )
dump( e₄ )

names( Main )

Figured it out… I can do

Expr( :curly, Symbol( :S, x), Expr( :(<:), :𝒯, :Real) )
1 Like

Probably easier to just use interpolation, e.g. :($S{𝒯<:Real}) if you have a variable S containing the desired symbol, or

:($(Symbol(:S, x)){𝒯<:Real})

to interpolate Symbol(:S, x).

1 Like

I think the easiest way is to use @eval to interpolate the symbol into the code:

julia> x = :S
:S

julia> @eval struct $x{𝒯<:Real}
       end

julia> S{Rational}()
S{Rational}()

Or if you need to store the full struct expression in a variable, interpolate into a quote block instead:

julia> y = :T
:T

julia> expr = quote
           struct $y{𝒯<:Real}
           end
       end
quote
    #= REPL[9]:2 =#
    struct T{𝒯 <: Real}
        #= REPL[9]:2 =#
    end
end

julia> eval(expr)

julia> T{AbstractFloat}()
T{AbstractFloat}()
1 Like

Thank you. Syntax is everything!