I think you just missed a bracket, you want T($(fieldAdditionExprs...)) splatting before interpolation, not T($fieldAdditionExprs...).
julia> struct StateVector
a :: Int
b :: Float64
end
julia> @generated function Base.:+(left::T,right::T) where T <: StateVector
@show fieldNames = fieldnames(T)
@show fieldAdditionExprs = [ :(left.$n + right.$n) for n in fieldNames ]
return :(
T($(fieldAdditionExprs...))
)
end
julia> StateVector(1,2.0) + StateVector(3,4.0)
fieldNames = fieldnames(T) = (:a, :b)
fieldAdditionExprs = [$(Expr(:quote, :(left.:($(Expr(:$, :n))) + right.:($(Expr(:$, :n)))))) for n = fieldNames] = Expr[:(left.a + right.a), :(left.b + right.b)]
StateVector(4, 6.0)
Edit, but @aplavin 's solution is certainly easier to read:
julia> using ConstructionBase
julia> Base.:*(x:: StateVector, y:: StateVector) = StateVector(map(*, getfields(x), getfields(y))...)
julia> StateVector(1,2.0) * StateVector(3,4.0)
StateVector(3, 8.0)