Help newbie to understand type stability please


#1

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]
end

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

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

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

#2

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]
end

Also see this suggestion in the manual.


#3

But why it is not a problem in good1?


#4

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


#5

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]
end
@code_warntype tst([1.])

#6

Looks like something goes wrong. Somewhat simplified:

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

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

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

#7

#8

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: