Help newbie to understand type stability please


Could anybody please help me improve my understanding of what looks like strange behavior?

function good1(x::Array{T,1}) where T<:Float64
    n = length(x)
    x *= 1  # problem is not here
    [i for i in x]

function good2(x::Array{T,1}) where T<:Float64
    n = length(x)
    [x[i] for i in 1:n]  # problem is not here

function wrong(x::Array{T,1}) where T<:Float64
    n = length(x)
    x *= 1 
    [x[i] for i in 1:n]

@code_warntype good1([0.])
@code_warntype good2([0.])
@code_warntype wrong([0.])    # also n is interpreted as Any here!


You make x change its type. Did you mean x .*= 1? Or you can use another variable, as in

function good3(x::Array{T,1}) where T<:Float64
    n = length(x)
    y = x * 1
    [y[i] for i in 1:n]

Also see this suggestion in the manual.


But why it is not a problem in good1?


BTW. I asked because I liked to give good answer on SO.


Another subquestion: Why is y “coreboxed” in next code? What does it mean? Or where could I find good documentation about it?

function tst(x::Array{T,1}) where T<:Float64
    n = length(x)
    n == 1 && return [1.0]
    y = x * 1
    [y[i] for i = 1:n]
@code_warntype tst([1.])


Looks like something goes wrong. Somewhat simplified:

function f(x)
    return [x[i] for i = 1:length(x)]

function g(x)
    x = x
    return [x[i] for i = 1:length(x)]

@code_warntype f([0])
@code_warntype g([0])



That (open!) issue has interesting milestone (0.5). (Probably label 1.0 is missing too?)

And yes - let could help avoid Core.Box. Thanks! :slight_smile: