What on earth does Any[...] do?

Interesting! This is a bit subtle, but it’s a natural result of arrays attempting to promote their contents to a common type.

julia> Any[ [1,2,3], ["1","2","3"], [1.0,2.0,3.0] ]
3-element Array{Any,1}:
 [1, 2, 3]
 String["1", "2", "3"]
 [1.0, 2.0, 3.0]

julia> [ [1,2,3], ["1","2","3"], [1.0,2.0,3.0] ]
3-element Array{Array{Any,1},1}:
 Any[1, 2, 3]
 Any["1", "2", "3"]
 Any[1.0, 2.0, 3.0]

In the first case, the outer array has explicit element type Any so its elements are taken as is when constructing the array. In the second case, the outer array has no explicit element type so typejoin is called to try to find a “reasonable” common element type – which is Vector{Any} since all of the things passed to it are vectors but they don’t have a common element type. So they’re all converted to the type Vector{Any} before construction.

The thing that’s questionable here is whether arrays should recursively promote to a common type like this when it ends up “pessimizing” their individual element types so much. The motivation for the array promotion rule is (more common) cases like this:

julia> [ [1, 2, 3], [1, 0.5, 0.25, 0.125], [-1, -2] ]
3-element Array{Array{Float64,1},1}:
 [1.0, 2.0, 3.0]
 [1.0, 0.5, 0.25, 0.125]
 [-1.0, -2.0]

Here’s it’s much better in terms of types and performance to convert all of the internal arrays to a single common concrete element type. I’ve filed an issue about this: #24988 since it’s worth considering changing the array promotion rule here.

3 Likes