# Type instablility

I am playing with the `CartesianIndex` and here is a simple function to set the elements to 0 outside a centered N-sphere in a N-dimensional array.

``````julia> function test!(A::AbstractArray{T}, r::Int) where {T <: Real}
ctr = [(size(A, d)+1)/2 for d in 1:ndims(A)]
R = CartesianRange(size(A))
for I in R
(sum(abs2, (I.I .- ctr)) > r^2) && (A[I] = zero(T))
end
nothing
end
test! (generic function with 1 method)

julia> A = rand(5, 5)
5×5 Array{Float64,2}:
0.493302  0.536014  0.392092   0.913987  0.379203
0.059023  0.927097  0.859462   0.875942  0.832613
0.217616  0.137665  0.0311417  0.591856  0.598981
0.28981   0.670475  0.454813   0.60883   0.558579
0.523627  0.109789  0.343885   0.782731  0.386419

julia> @code_warntype test!(A, 2)
Variables:
#self#::#test!
A::Array{Float64,2}
r::Int64
I@_4::CartesianIndex{2}
#temp#@_5::CartesianIndex{2}
#5@_6::##5#6{Array{Float64,2}}
ctr::Array{Float64,1}
R::CartesianRange{CartesianIndex{2}}
#3::Base.IteratorsMD.##3#4
#5@_10::Base.IteratorsMD.##5#6{Int64}
#temp#@_11::CartesianIndex{2}
newtail::Tuple{Int64}
#temp#@_13::Tuple{Int64,Int64}
T::Any
shape::Tuple{Base.OneTo{Int64}}
iter::CartesianRange{CartesianIndex{1}}
newout::Base.OneTo{Int64}
C::Array{Float64,1}
keeps@_19::Tuple{Tuple{Bool},Tuple{Bool}}
Idefaults@_20::Tuple{Tuple{Int64},Tuple{Int64}}
#temp#@_21::Int64
keeps@_22::Tuple{Tuple{Bool}}
Idefaults@_23::Tuple{Tuple{Int64}}
#temp#@_24::Int64
keep@_25::Tuple{Bool}
Idefault@_26::Tuple{Int64}
#temp#@_27::Int64
A1::Any
keeps@_29::Tuple{}
Idefaults@_30::Tuple{}
#temp#@_31::Int64
keep@_32::Tuple{Bool}
Idefault@_33::Tuple{Int64}
#temp#@_34::Int64
ind1@_35::Base.OneTo{Int64}
keep@_36::Tuple{}
Idefault@_37::Tuple{}
#temp#@_38::Int64
ind1@_39::Base.OneTo{Int64}
keep@_40::Tuple{}
Idefault@_41::Tuple{}
#temp#@_42::Int64
I_1::CartesianIndex{1}
I_2::CartesianIndex{1}
val_1::Int64
val_2::Float64
result::Float64
I@_48::CartesianIndex{1}
i#660::Int64
I@_50::CartesianIndex{1}
n#659::Int64
i#658::CartesianIndex{0}
#temp#@_53::Bool
r#657::CartesianRange{CartesianIndex{1}}
A_1::Tuple{Int64,Int64}
A_2::Any
keep_1::Tuple{Bool}
keep_2::Tuple{Bool}
Idefault_1::Tuple{Int64}
Idefault_2::Tuple{Int64}
#temp#@_61::Any
fx::Float64
......
``````

How do I make this function type stable? Thanks!

You can try a function barrier (introduce a local function taking ctr and A as input)

Thanks for the reply! I am aware of using function barrier here. I want to know how to eliminate the type instability issue in this function altogether. Maybe not as easy as I expected.

I actually think it’s already type stable. The `Any`s are only for variables that are optimized out.

See https://github.com/JuliaLang/julia/pull/23280. On the latest nightly version of Julia, all of the `Any`s are replaced with `<optimized out>`.

Thanks for pointing this out! I think you are right. This function is already type stable.