Hello, I’m currently trying to implement merge on ComponentArrays. I’ve taken inspiration from NamedTuples in the stdlib here, and wrote a macro and a function: (instead of the Expr)
using ComponentArrays
c1 = ComponentArray(a=2, b=5)
c2 = ComponentArray(b=1, g=2)
macro append_component_array(parent_array, keyname, val)
return esc(:($parent_array = ComponentArray($parent_array, $keyname = $val) ))
end
function merge_test(cvec1::ComponentVector{T1}, cvec2::ComponentVector{T2}) where {T1, T2}
typed_dict = ComponentVector{promote_type(T1, T2)}(cvec1)
for key in valkeys(cvec2)
keyname = ComponentArrays.getval(key)
val = cvec2[key]
@append_component_array(typed_dict, keyname, val)
end
typed_dict
end
However, I can’t seem to get keyname to evaluate properly in the macro to a “variable”:
Macros don’t evaluate symbols, it expands during the definition, before the method is ran and before the variables have values. Your macro just interpolates :typed_dict, :keyname, and :val into a line typed_dict = ComponentArray(typed_dict, keyname = val). Forgetting the macro for a second, you need a different line where a keyword is a runtime Symbol value rather than a fixed variable name. Try typed_dict = ComponentArray(typed_dict; keyname => val)
I tried to use dump to use keyname as a variable, thinking it would work based on how I understood it. Though, the result is either a crash (if I try to interpolate the dump), or nothing (if I don’t).
dump prints a value in a tree-like way to a maximum depth defaulting at 8, then returns nothing. You’re interpolating the value nothing where a Symbol instance is expected for a keyword.
As the question stands, I doubt meta programming is the answer. In particular, I don’t see the value of the macro over a function.
Maybe you could explain what the end goal is and why you believe meta programming is the correct way to get there. I’m saying this, because more often than not, it isn’t.
I see. The better course of action is to open an issue with ComponentArrays.jl, or write a ChainRulesCore.rrule yourself. Ideally ultimately making a PR.