# Type stability

**URL:** <https://discourse.julialang.org/t/type-stability/3988>\
**Category:** General Usage\
**Created:** [May 30, 2017, 11:00am UTC](https://discourse.julialang.org/t/type-stability/3988 "2017-05-30T11:00:16Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gdkrmr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdkrmr/32/2791_2.png) [@gdkrmr](https://discourse.julialang.org/u/gdkrmr)\
**Post date:** [May 30, 2017, 11:00am UTC](https://discourse.julialang.org/t/type-stability/3988/1 "2017-05-30T11:00:16Z")

</div>

I don’t understand the following is not typestable,  
changing the `_p` assignment to a `mapreduce` call doesn’t help, subsetting `h` or a `for` loop helps:

```julia
function conf_int_sum{T}(p::T, h::Array{T}, eps::T)
    b1 = zero(T)
    b2 = one(T)
    b = (b1 + b2) / 2
    _p = sum(x -> (x >= b) ? x : zero(x), h)
    while abs(_p - p) > eps
        if _p > p
            b1 = b
        else 
            b2 = b
        end
        b = (b1 + b2) / 2
        _p = sum(x -> (x >= b) ? x : zero(x), h)
    end
    return b
end

function conf_int_mapreduce{T}(p::T, h::Array{T}, eps::T)
    b1 = zero(T)
    b2 = one(T)
    b = (b1 + b2) / 2
    _p = mapreduce(x -> (x >= b) ? x : zero(x), +, h)
    while abs(_p - p) > eps
        if _p > p
            b1 = b
        else 
            b2 = b
        end
        b = (b1 + b2) / 2
        _p = mapreduce(x -> (x >= b) ? x : zero(x), +, h)
    end
    return b
end

function conf_int_subset{T}(p::T, h::Array{T}, eps::T)
    b1 = zero(T)
    b2 = one(T)
    b = (b1 + b2) / 2
    _p = sum(h[h .>= b])
    while abs(_p - p) > eps
        if _p > p
            b1 = b
        else 
            b2 = b
        end
        b = (b1 + b2) / 2
        _p = sum(h[h .>= b])
    end
    return b
end

function conf_int_for{T}(p::T, h::Array{T}, eps::T)
    b1 = zero(T)
    b2 = one(T)
    b = (b1 + b2) / 2
    _p = zero(T)
    for i in h
        if i >= b
            _p += i
        end
    end
    while abs(_p - p) > eps
        if _p > p
            b1 = b
        else 
            b2 = b
        end
        b = (b1 + b2) / 2
        _p = zero(T)
        for i in h
            if i >= b
                _p += i
            end
        end
    end
    return b
end

# typestable:
@code_warntype conf_int_for(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
@code_warntype conf_int_subset(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
# not typestable:
@code_warntype conf_int_mapreduce(0.5f0, randn(Float32, 30, 30, 30), 1f-3)
@code_warntype conf_int_sum(0.5f0, randn(Float32, 30, 30, 30), 1f-3)

```

---

<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:** [May 30, 2017, 11:36am UTC](https://discourse.julialang.org/t/type-stability/3988/2 "2017-05-30T11:36:23Z")

</div>

Probably [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276) (one of the bugs that I dislike the most, for reason like this).

---

<div class="post-metadata">

**Author:** ![gdkrmr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdkrmr/32/2791_2.png) [@gdkrmr](https://discourse.julialang.org/u/gdkrmr)\
**Post date:** [May 30, 2017, 2:04pm UTC](https://discourse.julialang.org/t/type-stability/3988/3 "2017-05-30T14:04:02Z")

</div>

so this is because I use `b` inside of the closure?

---

<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:** [May 30, 2017, 2:35pm UTC](https://discourse.julialang.org/t/type-stability/3988/4 "2017-05-30T14:35:36Z")

</div>

Yes you can work around it by adding

```julia
let b = b
    sum(...)
end

```

on the two places you call `sum` in `conf_int_sum`.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [May 30, 2017, 4:57pm UTC](https://discourse.julialang.org/t/type-stability/3988/5 "2017-05-30T16:57:23Z")

</div>

In MicroLogging.jl I tried to automate the `let` workaround using a macro. It turned out to be a bit more work than expected, so I thought people might find it useful in a package. Here it is, in rough form:

[https://github.com/c42f/FastClosures.jl](https://github.com/c42f/FastClosures.jl)

I’m not sure about the time frame when this might be fixed properly in the compiler. If people find it useful, I can go to the effort of registering the package.
