Making `broadcast` compile-time inference more accurate

question

#1

Working on latest Julia, the following call is correctly inferred to be Vector{Int64}:

ww = [(1,2,3),(4,5,6)]
# this broadcast returns Vector{Int64}
broadcast(getindex,ww,1)

But,

qq = [(1,'a',1.0),(2,'b',2.0)]
broadcast(getindex,qq,1)

is only inferred weakly to be Vector{Union{Int,Char,Float64}}.
This is annoying, since broadcast(first,qq) is inferred better.

What should I define to help type-inference? Making broadcast(getindex,qq,Val{1}) accurately inferred is also sufficient (as without knowing the value 1 at compile-time there is actually no way to know which tuple element is chosen).

This can be useful in cases where a record is parsed into a multi-typed tuple.


#2

Hmm, I tried to reproduce it but failed:

v0.7.0-DEV.526> qq = [(1,'a',1.0),(2,'b',2.0)]
2-element Array{Tuple{Int64,Char,Float64},1}:
 (1, 'a', 1.0)
 (2, 'b', 2.0)

v0.7.0-DEV.526> broadcast(getindex,qq,1) |> typeof
Array{Int64,1}

#3

Do you mean 0.5.2? broadcast is much improved in Julia 0.6.


#4

latest Julia today means: Version 0.7.0-DEV.635.

but the problem is not with the return type, but with the inferred return type i.e.

@code_warntype broadcast(getindex,qq,1)

is Vector{Union{Int64,Char,Float64}} but broadcast(first,qq) has Vector{Int64} in @code_warntype and I want broadcast(getindex,qq,Val{1}) to do the same.


#5

Woof, that’s a hard one. You’re passing a value (1) rather than a type, and hoping that the type system will constant-propagate it. You might have more luck defining mygetindex to take a Val{1}. But beware that Val objects are full of traps for the unwary, see https://docs.julialang.org/en/latest/manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)-1 and the section immediately above it.