# Type stable mapreduce over NamedTuple keys

**URL:** https://discourse.julialang.org/t/type-stable-mapreduce-over-namedtuple-keys/35367
**Category:** General Usage
**Tags:** question
**Created:** [March 1, 2020, 5:44pm UTC](https://discourse.julialang.org/t/type-stable-mapreduce-over-namedtuple-keys/35367 "2020-03-01T17:44:06Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 1, 2020, 5:44pm UTC](https://discourse.julialang.org/t/type-stable-mapreduce-over-namedtuple-keys/35367/1 "2020-03-01T17:44:06Z")

</div>

I am trying to write a function that

1. picks _keys_ from a `NamedTuple`,
2. uses each key to obtain values from two objects (not necessarily `NamedTuple`s, they support `getproperty`, may have other properties not used by this function)
3. applies a function to each triplet,
4. sums the result.

Example that is _not_ type stable:

```julia
function ntpicker_naive(nt, a, b)
    mapreduce(k -> getproperty(a, k) * getproperty(b, k) * getproperty(nt, k), +,
              keys(nt))
end

```

I came up with a recursive implementation that is type stable for _short_ named tuples, but not long ones:

```julia

@inline _ntpicker(acc, a, b, ::NamedTuple{(),Tuple{}}) = acc

@inline function _ntpicker(acc, a, b, nt::NamedTuple{K}) where K
    K1 = first(K)
    v = values(nt)
    p1 = getproperty(a, K1) * getproperty(b, K1) * first(v)
    _ntpicker(acc + p1, a, b, NamedTuple{Base.tail(K)}(Base.tail(v)))
end

ntpicker(nt::NT, a, b) where {NT <: NamedTuple} = _ntpicker(0, a, b, nt)

nt2 = (c = 1, d = 2)
nt4 = (c = 1, d = 2, e = 3, f = 4)

@code_warntype ntpicker(nt2, nt2, nt2) # OK
@code_warntype ntpicker(nt4, nt4, nt4) # Any

```

Is there a way I could make this work for arbitrarily long `NamedTuple`s, or should I just use generated functions?
