# Create parametric structure with metaprogramming

I’m trying to use metraprogramming to create structures on the fly. I managed to make a construtor for a vanilla struct as:

``````function makestruct(name::Symbol, ndim::Integer)
dims = (:x, :y, :z)
fields = [:( \$(dims[i]) ) for i in 1:ndim]
@eval begin
struct \$(name)
\$(fields...)
end
end
end
``````

However, I can’t manage to make a parametric struct with metaprogramming. In the end what I would like to simply generate:

``````struct bar{T}
x::T
y::T
end
``````

or

``````struct bar{T}
x::T
y::T
z::T
end
``````

depending on `ndim`

It seems like your existing code is already almost there–you just need to add `T` in the appropriate places:

``````julia> function makestruct(name::Symbol, ndim::Integer)
dims = (:x, :y, :z)
fields = [:( \$(dims[i])::T ) for i in 1:ndim]
@eval begin
struct \$(name){T}
\$(fields...)
end
end
end
makestruct (generic function with 1 method)

julia> makestruct(:bar, 2)

julia> bar(1, 2)
bar{Int64}(1, 2)

``````
1 Like

Oh thanks I was unsuccesfuly trying to parse the ::T directly inside the eval call

By the way, you might be interested in `StaticArrays.FieldVector`, which is designed to let types like this operate as statically sized vectors in a convenient way: API · StaticArrays.jl

Oh, and also, if your actual use-case really is small vectors with `x, y, z` labels, note that you can already use `StaticArrays.SVector` for that with no changes at all:

``````julia> using StaticArrays

julia> v = SVector{2, Float64}(1.0, 2.0)
2-element SVector{2, Float64} with indices SOneTo(2):
1.0
2.0

julia> v.x
1.0

julia> v.y
2.0
``````

Thanks for the suggestion, but in this particular case `x, y, z` will either be 2 or 3 dimensional arrays too large for `StaticArrays`.

1 Like