# A function to add two flat structs

**URL:** https://discourse.julialang.org/t/a-function-to-add-two-flat-structs/6302
**Category:** New to Julia
**Created:** [October 7, 2017, 2:19am UTC](https://discourse.julialang.org/t/a-function-to-add-two-flat-structs/6302 "2017-10-07T02:19:07Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![tuckermcclure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tuckermcclure/32/1187_2.png) [@tuckermcclure](https://discourse.julialang.org/u/tuckermcclure)
#### Post date: [October 7, 2017, 2:19am UTC](https://discourse.julialang.org/t/a-function-to-add-two-flat-structs/6302/1 "2017-10-07T02:19:07Z")

</div>

I’d like to be able to add two structs without knowing about the structs ahead of time, such as:

```julia
function Base.:+(a::T, b::T) where {T}
    T((getfield(a, field) + getfield(b, field) for field in fieldnames(a))...)
end

```

I find that for a simple struct (with an int and a float) that this takes about a microsecond, which is much longer than I expected.

I also tried it this way with mutable structs:

```julia
function Base.:+(a::T, b::T) where {T}
    s = deepcopy(a)
    for field in fieldnames(a)
        setfield!(s, field, getfield(a, field) + getfield(b, field))
    end
    return s
end

```

That takes about 2us.

If I hard-code the addition, like so:

```julia
addem(x::MyType, y::MyType) = MyType(x.a + y.a, x.b + y.b)

```

it only takes about 20ns. This is more like what I’m hoping for, but without hard-coding the addition.

Is there a better way to do this generally?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [October 7, 2017, 3:00am UTC](https://discourse.julialang.org/t/a-function-to-add-two-flat-structs/6302/2 "2017-10-07T03:00:58Z")

</div>

> [@tuckermcclure](#):
>
> Is there a better way to do this generally?

Use a generated function to build the `MyType` addition statement using `fieldnames`.

Here’s an example of a function that copies all field of a generic abstract type. It’s similar to what you want and should be easy to modify.

[https://github.com/JuliaDiffEq/DiffEqBase.jl/blob/master/src/data\_array.jl#L57](https://github.com/JuliaDiffEq/DiffEqBase.jl/blob/master/src/data_array.jl#L57)

---

<div class="post-metadata">

### Author: ![tuckermcclure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tuckermcclure/32/1187_2.png) [@tuckermcclure](https://discourse.julialang.org/u/tuckermcclure)
#### Post date: [October 7, 2017, 4:42am UTC](https://discourse.julialang.org/t/a-function-to-add-two-flat-structs/6302/3 "2017-10-07T04:42:00Z")

</div>

Wow, thanks @ChrisRackauckas. Here’s my first take at a generated function:

```julia
@generated function Base.:+(x::T, y::T) where T
    expr = ( :(x.$f + y.$f) for f in fieldnames(T) ) # Make a tuple of expressions to add each field
    :( T($(expr...)) ) # Splat them into an expression for a constructor for a T type
end

```

This only takes ~20ns or so, just like the hard-coded version.
