# Anonymous functions weird behaviour with Array{Arrays}

I waned to ask you about a weird thing that happens to me when I use anonymous functions with `Array{Array}`:

``````L = x -> [x[1:4],reshape(x[5:8],2,2)] #my anonymous functions generates an Array{Array{Float64,N},1}
L(randn(8))
2-element Array{Array{Float64,N},1}:
[-0.557195,-1.62936,-0.340156,-0.947051]
[2.19154 0.160976; 1.1349 0.201494]
``````

then if I sum this directly with an `Array{Array{Float64,N},1}` I should also get an `Array{Array{Float64,N},1}`!
but this is what happens:

``````L(randn(8))+[randn(4),randn(2,2)]
2-element Array{Array{T,N},1}:
[0.703503,-1.38808,-0.641571,1.70502]
[-1.86622 -1.91455; 2.22344 0.450923]
``````

but this actually gives an `Array{Array{T,N},1}`. Isnâ€™t this weird? Or am I doing something wrong?

This isnâ€™t related to anonymous functions, as it can be reproduced like this:

``````julia> a = [[1], [2 3]]
2-element Array{Array{Int64,N},1}:
[1]
[2 3]

julia> a + a
2-element Array{Array{T,N},1}:
[2]
[4 6]
``````

Compare the types in above code with post #6.

1 Like

It is generally not a good idea to mix objects of different types in an array. What are you trying to do? You could try using a tuple instead.

No, youâ€™re not doing anything wrong. These types are determined by inference, and inference is an imperfect approximation. Thereâ€™s no limit to how hard inference could try to get types as exact as possible â€” and indeed it will never be able to figure out some cases (see: Halting problem - Wikipedia). So at some point it must give up and return an approximation. The only question is where to draw that line.

In my experience, once inference can no longer concretely figure out one of the parameters (N in this case), it doesnâ€™t â€śtryâ€ť as hard to figure out the other parameters. If, instead, you make sure that all the inner arrays are two-dimensional, itâ€™s able to determine the types exactly.

2 Likes

well tuples are not really attractive as they are sometimes difficult to deal with. say I want to sum two of them I cannot simply write `a+b`. Is it that wrong to use Array{Array} with different sizes? Thank you!

Different sizes per se is not the problem, different number of dimensions is. Compare e.g.

``````julia> a=[hcat([1]), [2 3]]
2-element Array{Array{Int64,2},1}:
[1]
[2 3]

julia> a+a
2-element Array{Array{Int64,2},1}:
[2]
[4 6]
``````
2 Likes

This I understand, but why is it `T` instead of `Any`? I find this confusing.

The `T` in `Vector{T}` represents a TypeVar wildcard â€” it can indeed match any type. It might be a `Vector{Any}`, but it could also be a `Vector{Int}` or `Vector{Real}`. This may get more obvious in the future as there are changes planned to how this prints. It might eventually be printed as `Vector{T} where T <: Any`.

This is different from `Any` in `Vector{Any}` â€” here Julia actually knows more about the type. It knows that it will definitely be a heterogenous array that can contain any object.

This is particularly significant because Juliaâ€™s type parameters are invariant.

1 Like

Iâ€™m not sure what changed, but this `T` output only happens on 0.5. On a recent (~ 2 days) trunk build I get:

``````julia> L = x -> [x[1:4],reshape(x[5:8],2,2)]
(::#1) (generic function with 1 method)

julia> L(randn(8))+[randn(4),randn(2,2)]
2-element Array{Array{Float64,N},1}:
[0.472211,0.0546804,0.613357,0.422507]
[2.78885 -0.646303; -0.120245 -0.950541]
``````

(and `2-element Array{Array{Int64,N},1}` for #4)

2 Likes