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

**URL:** <https://discourse.julialang.org/t/what-on-earth-does-any-do/7625>\
**Category:** General Usage\
**Created:** [December 8, 2017, 3:04pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625 "2017-12-08T15:04:56Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![NickNack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicknack/32/1792_2.png) [@NickNack](https://discourse.julialang.org/u/NickNack)\
**Post date:** [December 8, 2017, 3:04pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/1 "2017-12-08T15:04:56Z")

</div>

I’ve been using Julia nearly daily for about a year and thought I was fluent in the basics by now. Here’s an example that proves I was mistaken.

(I believe that) The syntax `T[]` defines an array literal and casts the elements to type `T`. For example:

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

```

Similarly, (I believe that) `Any[]` is useful for initializing an array with elements of type `Any`, so that it can hold elements of other types later.

```julia
julia> Any[1,2,3]
3-element Array{Any,1}:
 1
 2
 3

```

So far so good. Now let’s do the same thing on a more complex array:

```julia
julia> x = 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> typeof.(x)
3-element Array{DataType,1}:
 Array{Int64,1}
 Array{String,1}
 Array{Float64,1}

```

Instead of casting the elements of `x` to Any, it seems to have done the complete opposite and made the types more specific. On a heterogeneous array, I would have expected `Any[]` to produce output similar to what you get if you leave out the `Any` specification, like this:

```julia
julia> y = [[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]

```

What in the world is going on here? What is this called, and where is it documented? (Googling “Julia Any” isn’t very helpful …)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 8, 2017, 3:09pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/2 "2017-12-08T15:09:33Z")

</div>

> [@NickNack](#):
>
> T defines an array literal and casts the elements to type T.

```julia
julia> typeof(convert(Any, 1))
Int64

julia> typeof(convert(Any, "foo"))
String

```

in fact

```julia
convert(::Type{Any}, x) = x

```

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [December 8, 2017, 3:15pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/3 "2017-12-08T15:15:11Z")

</div>

`Any` is an abstract type, so you can’t have concrete instantiations of it. However, containers can have `Any` as their element type. When this is true it is required that the elements of the array have types `<: Any`, but since `Any` is an abstract type (and all concrete types are subtypes of it), `convert(Any, x) = x`, \forall x.

When you do `x = Any[[1,2,3], ["1","2","3"], [1.0,2.0,3.0]]` all you are doing is declaring that your Array should have `eltype` `Any`. Since `Vector{Int64} <: Any`, `Vector{String} <: Any` and `Vector{Float64} <: Any`, this constructor is perfectly valid and the conversions that take place are trivial.

It’s a little less clear to me why the result is different when you omit the prefixed `Any`, but it’s just a result of how the compiler processes literals.

---

<div class="post-metadata">

**Author:** ![Non-Contradiction](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-contradiction/32/2208_2.png) [@Non-Contradiction](https://discourse.julialang.org/u/Non-Contradiction)\
**Post date:** [December 8, 2017, 3:51pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/4 "2017-12-08T15:51:29Z")

</div>

I think the correct question is what does `[[x1, y1, z1], [x2, y2, z2], [x3, y3, z3]]` do instead of `Any[...]` do.  
`[[x1, y1, z1], [x2, y2, z2], [x3, y3, z3]]` will try to cast all the elements into a common type, and in your example, the common type if `Any`, so it is the behaviour of

```julia
julia> y = [[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]

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 8, 2017, 3:52pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/5 "2017-12-08T15:52:07Z")

</div>

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

```julia
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
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](https://github.com/JuliaLang/julia/issues/24988) since it’s worth considering changing the array promotion rule here.

---

<div class="post-metadata">

**Author:** ![Non-Contradiction](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-contradiction/32/2208_2.png) [@Non-Contradiction](https://discourse.julialang.org/u/Non-Contradiction)\
**Post date:** [December 8, 2017, 4:08pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/6 "2017-12-08T16:08:46Z")

</div>

BTW, `T[]` will only cast the elements to type `T`. In the case of vector of vectors, you need to do something like `Vector{T}[]` to convert the elements in the inner vectors, for example, `Vector{Any}[[1,2,3], ["1","2","3"], [1.0,2.0,3.0] ]` will cast all the elements in the inner vectors to type `Any`.

---

<div class="post-metadata">

**Author:** ![austinbean](https://avatars.discourse-cdn.com/v4/letter/a/839c29/32.png) [@austinbean](https://discourse.julialang.org/u/austinbean)\
**Post date:** [December 8, 2017, 5:30pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/7 "2017-12-08T17:30:35Z")

</div>

This is off topic, but can I ask about this  
`convert(::Type{Any}, x) = x`  
syntax?

Specifically the `::Type{Any}` part. How is that understood by `convert` in this example?

Does `::Type{Any}` refer to the type itself? Or an instance of the type?

I see that I can do

```julia
function f1(::Array{Int64})
   return true # returns true as long as the argument is <: Array{Int64}, I think?
end 

```

but not

```julia
function f2(Array{Int64})

```

which is a syntax error.

I guess I could use `::Type{Any}` to test that whatever is passed to `f1` is an instance of the type. Are there other uses for this syntax? Is there some syntax that would let me do:

```julia
function f3(::Array{Int64})
   return size( the argument ) # but how do I refer to that in this scope?
end

```

I see this syntax around sometimes but I don’t think I fully get it.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 8, 2017, 6:31pm UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/8 "2017-12-08T18:31:26Z")

</div>

For any Julia type `T`, we have `T::Type{T}`. This lets you write functions that dispatch on a particular type passed in as an argument:

```julia
julia> f(::Type{<:AbstractFloat}) = "a type which is float-like"
f (generic function with 2 methods)

julia> f(::Type{Int}) = "the type Int"
f (generic function with 3 methods)

julia> f(::Type{String}) = "the type String"
f (generic function with 4 methods)

julia> f(Float64)
"a type which is float-like"

julia> f(Int)
"the type Int"

julia> f(String)
"the type String"

```

this should actually look weird, because it’s kind of like we’re dispatching on the _value_ of the argument rather than its type. After all, `Int, Float64` and `String` are all just values of type `DataType`:

```julia
julia> typeof(Int)
DataType

```

But because dispatching on types as function arguments is so useful, the `Type` construct is specifically designed to make that possible. This leads to a particular weirdness:

```julia
julia> Int::Type{Int}
Int64

julia> Int isa Type{Int}
true

julia> typeof(Int)
DataType

julia> typeof(Int) == Type{Int}
false

```

fortunately, that’s the only weirdness. Otherwise, `Type` arguments are just like any other function argument; they just look weird because they’re often written as `f(::Type{T})` with the variable name omitted rather than `f(x::Type{T})`. Including the variable name makes the behavior more clear:

```julia
julia> function f(x::Type{T}) where T
         @show x
         @show T
         @assert x == T
       end
f (generic function with 1 method)

julia> f(Int)
x = Int64
T = Int64

julia> f(Real)
x = Real
T = Real

julia> f(Float64)
x = Float64
T = Float64

```

You can see in this case why the variable name `x` is typically omitted, because its value (the type that was passed to `f`) is already captured in the variable `T`. So we would generally write `f` as:

```julia
julia> function f(::Type{T}) where T
         @show T
       end
f (generic function with 1 method)

julia> f(Int)
T = Int64
Int64

julia> f(Real)
T = Real
Real

```

and refer to the type as `T` inside the function.

The most common place to see `Type{T}` is in `convert()` methods:

```julia
convert(::Type{MySpecialType}, x::Int) = make_my_special_type_from_int(x)
convert(::Type{Int}, y::MySpecialType) = make_int_from_my_special_type(y)

```

since `convert` is called with the destination type as its first argument:

```julia
y = convert(MySpecialType, 1)
convert(Int, y)

```

Regarding your last question:

> `function f3(::Array{Int64})`  
> ` return size( the argument ) # but how do I refer to that in this scope?`  
> `end`

dispatching with `Type{T}` is useful when you expect a _type_ as an argument, not an _instance_ of that type. So your `f3` would just be:

```julia
function f3(x::Array{Int64})
  return size(x)
end

```

just like any other method in Julia.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 15, 2017, 4:55am UTC](https://discourse.julialang.org/t/what-on-earth-does-any-do/7625/9 "2017-12-15T04:55:37Z")

</div>

Update: so, I ran those examples in a 0.6 session without realizing it. This is already changed/fixed on master:

```julia
julia> VERSION
v"0.7.0-DEV.2976"

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

```
