# Why isn't this function type stable?

**URL:** <https://discourse.julialang.org/t/why-isnt-this-function-type-stable/64244>\
**Category:** General Usage\
**Tags:** type-stability\
**Created:** [July 7, 2021, 11:50pm UTC](https://discourse.julialang.org/t/why-isnt-this-function-type-stable/64244 "2021-07-07T23:50:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Arrigo\_Benedetti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/arrigo_benedetti/32/25545_2.png) [@Arrigo\_Benedetti](https://discourse.julialang.org/u/Arrigo_Benedetti)\
**Post date:** [July 7, 2021, 11:50pm UTC](https://discourse.julialang.org/t/why-isnt-this-function-type-stable/64244/1 "2021-07-07T23:50:51Z")

</div>

Let’s consider the function:

```julia
using Sobol

function fun_pdf(img1::Matrix{T}, n_skip) where T <: Real
    (nrows, ncols) = size(img1)
    
    indx = SobolSeq([0, 0], [ncols - 1, nrows - 1])
    indx = skip(indx, n_skip)

    n_samples = Int(floor(nrows * nrows * 0.1))

    for i in 1:n_samples
        ix = next!(indx)
        #xq, yq = ceil(Int, ix[1]), ceil(Int, ix[2])
        xq, yq = ceil(Int64, ix[1]), ceil(Int64, ix[2])
    end
end

```

Even with

```julia
xq, yq = ceil(Int64, ix[1]), ceil(Int64, ix[2])

```

instead of

```julia
xq, yq = ceil(Int, ix[1]), ceil(Int, ix[2])

```

the compiler can’t infer the type of `xq` and `yq`:

```julia
PDF = zeros(Float64,nf1,nf2)
@code_warntype fun_pdf(PDF, 100)

Variables
  #self#::Core.Const(fun_pdf)
  img1::Matrix{Float64}
  n_skip::Int64
  @_4::Union{Nothing, Tuple{Int64, Int64}}
  @_5::Int64
  n_samples::Int64
  indx::ScaledSobolSeq{_A, Int64} where _A
  ncols::Int64
  nrows::Int64
  i::Int64
  yq::Any
  xq::Any
  ix::AbstractVector{var"#s7"} where var"#s7"<:AbstractFloat

Body::Nothing
1 ─ %1 = Main.size(img1)::Tuple{Int64, Int64}
│ %2 = Base.indexed_iterate(%1, 1)::Core.PartialStruct(Tuple{Int64, Int64}, Any[Int64, Core.Const(2)])
│ (nrows = Core.getfield(%2, 1))
│ (@_5 = Core.getfield(%2, 2))
│ %5 = Base.indexed_iterate(%1, 2, @_5::Core.Const(2))::Core.PartialStruct(Tuple{Int64, Int64}, Any[Int64, Core.Const(3)])
│ (ncols = Core.getfield(%5, 1))
│ %7 = Base.vect(0, 0)::Vector{Int64}
│ %8 = (ncols - 1)::Int64
│ %9 = (nrows - 1)::Int64
│ %10 = Base.vect(%8, %9)::Vector{Int64}
│ (indx = Main.SobolSeq(%7, %10))
│ (indx = Main.skip(indx, n_skip))
│ %13 = (nrows * nrows * 0.1)::Float64
│ %14 = Main.floor(%13)::Float64
│ (n_samples = Main.Int(%14))
│ %16 = (1:n_samples)::Core.PartialStruct(UnitRange{Int64}, Any[Core.Const(1), Int64])
│ (@_4 = Base.iterate(%16))
│ %18 = (@_4 === nothing)::Bool
│ %19 = Base.not_int(%18)::Bool
└── goto #4 if not %19
2 ┄ %21 = @_4::Tuple{Int64, Int64}::Tuple{Int64, Int64}
│ (i = Core.getfield(%21, 1))
│ %23 = Core.getfield(%21, 2)::Int64
│ (ix = Main.next!(indx))
│ %25 = Base.getindex(ix, 1)::Any
│ %26 = Main.ceil(Main.Int64, %25)::Any
│ %27 = Base.getindex(ix, 2)::Any
│ %28 = Main.ceil(Main.Int64, %27)::Any
│ (xq = %26)
│ (yq = %28)
│ (@_4 = Base.iterate(%16, %23))
│ %32 = (@_4 === nothing)::Bool
│ %33 = Base.not_int(%32)::Bool
└── goto #4 if not %33
3 ─ goto #2
4 ┄ return nothing

```

Any ideas?

---

<div class="post-metadata">

**Author:** ![jacobadenbaum](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@jacobadenbaum](https://discourse.julialang.org/u/jacobadenbaum)\
**Post date:** [July 8, 2021, 1:32am UTC](https://discourse.julialang.org/t/why-isnt-this-function-type-stable/64244/2 "2021-07-08T01:32:10Z")

</div>

The `ScaledSobolSeq` object you’re constructing needs to know the dimension (as part of it’s type information).

You can either:

- construct `indx` outside the function, and use a function barrier, or
- provide the type information directly yourself. I.e, write

```julia
indx = ScaledSobolSeq{2, Float64}(Float64[0,0], Float64[ncols -1, nrows-1])

```

of course, there may be another option that I’m missing!
