I’m trying to write a function to “vectorize” a struct. A plain struct would be defined like:
struct Bus{T}
vm::T
end
And I want the output to be:
struct BusVec{T}
vm::Vector{T}
end
A function is implemented below by parsing the defined Bus
to get the field names and types. A struct
expression will be created and eval
ed.
The problem is that the newly created struct does not have any constructor.
Copy-and-paste MWE:
"""
This is the MWE of some function to derive a new type from a defined type.
"""
function generate_vector_type(::Type{T}) where T
struct_name = Symbol(nameof(T), "Vec")
fields = fieldnames(T)
# Get field information from the original type definition
type_def = Base.unwrap_unionall(T)
field_types = type_def.types
# Create vectorized field expressions
field_exprs = [:($(fields[i])::Vector{$(field_types[i])}) for i in eachindex(fields)]
# Get type parameters, ignore supertype for now
type_params = if T isa UnionAll
[T.var.name]
else
T.parameters
end
# Construct the type expression with parameters
param_expr = if !isempty(type_params)
Expr(:curly, struct_name, type_params...)
else
struct_name
end
# Generate struct definition
struct_expr = Expr(:struct, true,
param_expr,
Expr(:block, field_exprs...)
)
return struct_expr
end
struct Bus{T}
vm::T
end
expr = generate_vector_type(Bus)
@show expr
eval(expr)
methods(BusVec)
Ouputs
expr = :(mutable struct BusVec{T}
vm::Vector{T}
end)
# 0 methods for type constructor
I then copied expr
, renamed the struct, and run it in the same REPL, the default constructor is generated.
mutable struct BusVec2{T}
vm::Vector{T}
end
methods(BusVec2)
This gives
# 1 method for type constructor:
BusVec2(vm::Vector{T}) where T in Main at In[24]:2
I’m suspecting rules/scoping issues related to eval
but couldn’t figure it out after a day. Any suggestions are appreciated!