# IterTools.jl Partition type stability?

**URL:** <https://discourse.julialang.org/t/itertools-jl-partition-type-stability/13847>\
**Category:** Performance\
**Tags:** iterators, itertoolspartition\
**Created:** [August 21, 2018, 7:09pm UTC](https://discourse.julialang.org/t/itertools-jl-partition-type-stability/13847 "2018-08-21T19:09:17Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![gabrielgellner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gabrielgellner/32/75_2.png) [@gabrielgellner](https://discourse.julialang.org/u/gabrielgellner)\
**Post date:** [August 21, 2018, 7:09pm UTC](https://discourse.julialang.org/t/itertools-jl-partition-type-stability/13847/1 "2018-08-21T19:09:17Z")

</div>

Trying some code like:

```julia-auto
function test_loop(event_times)
    out = 0.0
    for (i, event_time) in partition(event_times, 2, 1)
        out += i + event_time
    end
    return out
end

@code_warntype test_loop([1.1, 1.8, 2.1, 3.2, 5.1])

```

And I get lots of scary highlighting. Am I doing something iffy? I just want a nice sliding window like function. Looked at the IterTools code a bit but don’t fully understand what might be causing the issue.

Thanks so much

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 22, 2018, 5:02pm UTC](https://discourse.julialang.org/t/itertools-jl-partition-type-stability/13847/2 "2018-08-22T17:02:47Z")

</div>

`partition` uses the runtime value of the second argument as one of the parameters in the resulting type, which is type unstable.

Note that for constant values this can be fixed by inlining the constructor and exploiting constant propagation as shown by:

```julia
julia> @code_warntype f(event_times)
Body::IterTools.Partition{Array{Float64,1},_1} where _1
1 1 ─ %1 = invoke Main.partition(_2::Array{Float64,1}, 2::Int64, 1::Int64)::IterTools.Partition{Array{Float64,1},_1} where _1 │
  └── return %1 │

julia> @eval IterTools begin # only adding @inline to the constructor, rest is the same
       @inline function partition(xs::I, n::Int, step::Int) where I
           if step < 1
               throw(ArgumentError("Partition step must be at least 1."))
           end

           if n < 1
               throw(ArgumentError("Partition size n must be at least 1"))
           end

           Partition{I, n}(xs, step)
       end
       end

julia> @code_warntype f(event_times)
Body::IterTools.Partition{Array{Float64,1},2}
1 1 ─ %1 = %new(IterTools.Partition{Array{Float64,1},2}, event_times, 1)::IterTools.Partition{Array{Float64,1},2} │╻╷ partition
  └── return %1

```

With this, the original example infers fine as well.

---

<div class="post-metadata">

**Author:** ![gabrielgellner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gabrielgellner/32/75_2.png) [@gabrielgellner](https://discourse.julialang.org/u/gabrielgellner)\
**Post date:** [August 22, 2018, 5:25pm UTC](https://discourse.julialang.org/t/itertools-jl-partition-type-stability/13847/3 "2018-08-22T17:25:07Z")

</div>

Oh man this is above my level of understanding, but it works sweet. Is this something to try to push into IterTools itself? Or would there be a reason not to do this?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 22, 2018, 5:39pm UTC](https://discourse.julialang.org/t/itertools-jl-partition-type-stability/13847/4 "2018-08-22T17:39:28Z")

</div>

Inlining too many things can bloat the code, but if it is a common thing to call `partition` with a literal for `n` then it probably makes sense since having things infer is nice. There are other possible solutions that involves changing the API for how `partition` is called or how the `Partition` struct is defined but this seems like a pretty simple solution, at least for this use-case.
