# Zero-dimensional arrays are acting strange

**URL:** <https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909>\
**Category:** New to Julia\
**Tags:** arrays\
**Created:** [March 31, 2023, 7:00pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909 "2023-03-31T19:00:15Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [March 31, 2023, 7:00pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/1 "2023-03-31T19:00:16Z")

</div>

I can can create a zero dimensional array of Nothing:

```julia
julia> Array{Nothing, 0}(nothing)
0-dimensional Array{Nothing, 0}:
nothing

```

but not other types:

```julia
julia> Array{String, 0}("")
ERROR: MethodError: no method matching Array{String, 0}(::String)

julia> Array{Tuple{Nothing}, 0}((nothing,))
ERROR: MethodError: no method matching Array{Tuple{Nothing}, 0}(::Tuple{Nothing})

julia> Array{Vector, 0}([])
ERROR: MethodError: no method matching Array{Vector, 0}(::Vector{Any})

```

I can crete a zero dimensional array of Union{Nothing, Float64} with nothing and then update the value in it to Float64.

```julia
julia> x = Array{Union{Nothing, Float64}, 0}(nothing)
0-dimensional Array{Union{Nothing, Float64}, 0}:
nothing

julia> x[] = 1.1
1.1

```

But I cannot initialize the array with a Float64.

```julia
julia> x = Array{Union{Nothing, Float64}, 0}(1.2)
ERROR: MethodError: no method matching Array{Union{Nothing, Float64}, 0}(::Float64)

```

Can someone tell me what’s going on? I don’t know computer science.

---

<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:** [March 31, 2023, 7:43pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/2 "2023-03-31T19:43:59Z")

</div>

The issue here is that this method isn’t for initializing an array with values. It’s only for initializing an array with an “initializer” object, which can be one of `undef`, `nothing` or `missing`, telling `Array` how to initialize the array initially. This is documented in the [docstring of the Array constructor](https://docs.julialang.org/en/v1/base/arrays/#Core.Array-Tuple%7BUndefInitializer,%20Any%7D). If you want a zero-dimensional array from a value, you can ues the `fill` function with a single argument:

```julia
julia> fill(1.1)
0-dimensional Array{Float64, 0}:
1.1

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [March 31, 2023, 7:51pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/3 "2023-03-31T19:51:39Z")

</div>

Why do these special cases missing/nothing exist?

`Array{Union{Float32,Missing}}(missing, 1,3)` is (roughly?) a special syntax for `fill!(Array{Union{Float32,Missing}}(undef, 1,3), missing)`, but the docs don’t really offer a reason to treat these two specially. Is there some optimsation these allow? Trying to time them doesn’t reveal much.

Presumably they cannot be removed before 2.0, but can they be marked as weird discouraged special cases? With a pointer to `fill` or `fill!(... undef ...` as the generic thing?

---

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [March 31, 2023, 7:58pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/4 "2023-03-31T19:58:12Z")

</div>

I see, so this is nothing specific to zero-dimensional arrays. It’s true for Arrays generally.

I saw a discussion elsewhere too, but this means that if you want to initialize an array that takes, say `Int64`, you’ll need to actually create an array that accepts `Union{Nothing, Int64}`. Seems clunky and confusing, but what do I know?

Also confusing because `Array{Int64, 1}()` works but `Array{Int64, 0}()` and `Array{Int64, 2}()` don’t.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [March 31, 2023, 8:10pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/5 "2023-03-31T20:10:29Z")

</div>

> [@sadish-d](#):
>
> but this means that if you want to initialize an array that takes, say `Int64`, you’ll need to actually create an array that accepts `Union{Nothing, Int64}`.

No, you don’t. You can write `fill(1, 2, 3)` or `fill!(Array{Int}(undef, 2, 3), 1)`. These are the same for all types.

The nothing/missing cases are weird confusing extras.

> `Array{Int64, 1}()` works

This seems to be another weird confusing edge case. (And undocumented?) This array is empty, so perhaps the logic is that the constructor need not care whether you asked for it uninitialised or what. `Array{Int64, 1}(undef, 0)` would be more standard, or just `Int[]`. `Array{Int64, 2}()` does not work; I suppose there are many sizes an empty matrix could have, like `fill(99, 0, 1)` or `fill(99, 3, 0)`.

---

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [March 31, 2023, 8:16pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/6 "2023-03-31T20:16:13Z")

</div>

@mcabbott I should have said “to initialize a placeholder array that **later** takes `Int64`”. I understand that `fill` works if you already know what you want to put in the array.

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [March 31, 2023, 8:17pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/7 "2023-03-31T20:17:22Z")

</div>

> [@sadish-d](#):
>
> “to initialize a placeholder array that **later** takes `Int64`”.

I think this is usually called an uninitialised array – you create the array, but don’t initialise its values. This is what `undef` is for. (And `similar`.) You should not touch missing/nothing unless you have reason to store those objects in your array.

---

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [March 31, 2023, 8:21pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/8 "2023-03-31T20:21:07Z")

</div>

I guess it makes sense that it’s called “uninitialized”. I am not familiar with computer science terminology. But thanks for the note on `undef`.

---

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [March 31, 2023, 8:52pm UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/9 "2023-03-31T20:52:34Z")

</div>

For anyone interested, here’s some earlier discussion on a similar topic. People smarter than I also tend to think that behavior of `Array{Int64, 1}()`, `Array{Int64, 0}()`, `Array{Int64, 2}()` is inconsistent.

> [@Why does Array{Int}() product Array{Int, 0} and not Array{Int, 1}](https://discourse.julialang.org/t/why-does-array-int-product-array-int-0-and-not-array-int-1/11298/25):
>
> Union{Missing, T} is not 100% as fast as just using T, causes more allocations, and is not compatible with C code: julia\> struct Foo x::Int end julia\> struct FooM x::Union{Missing,Int} end julia\> function fillfoo(T,n) ret = Array{T}(undef, n) for k = 1:n ret[k] = T(1) ret end end julia\> @time fillfoo(Foo, 100000); 0.046550 seconds (199.50 k allocations: 3.808 MiB) julia\> @time fillfoo(FooM, 100000); 0.049624 seconds (…

---

<div class="post-metadata">

**Author:** ![blackeneth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blackeneth/32/10353_2.png) [@blackeneth](https://discourse.julialang.org/u/blackeneth)\
**Post date:** [April 1, 2023, 2:10am UTC](https://discourse.julialang.org/t/zero-dimensional-arrays-are-acting-strange/96909/10 "2023-04-01T02:10:58Z")

</div>

Here is a long discussion on how [#undef came about.](https://github.com/JuliaLang/julia/issues/24595)
