# Subsetting uninitialized arrays

**URL:** https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449
**Category:** Internals & Design
**Tags:** question
**Created:** [June 19, 2019, 2:54pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449 "2019-06-19T14:54:13Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [June 19, 2019, 2:54pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/1 "2019-06-19T14:54:13Z")

</div>

You can subset an uninitialized vector, e.g.:

```julia
julia> v = Vector{Any}(undef, 4)
4-element Array{Any,1}:
 #undef
 #undef
 #undef
 #undef

julia> v[:]
4-element Array{Any,1}:
 #undef
 #undef
 #undef
 #undef

```

But not a matrix:

```julia
julia> m = Matrix{Any}(undef, 2 , 2)
2×2 Array{Any,2}:
 #undef #undef
 #undef #undef

julia> m[:,:]
ERROR: UndefRefError: access to undefined reference

```

But you can do it if you drop a dimension:

```julia
julia> m[:]
4-element Array{Any,1}:
 #undef
 #undef
 #undef
 #undef

```

My question is whether this is intended and if not should it be fixed? Thank you.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [June 19, 2019, 3:28pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/2 "2019-06-19T15:28:41Z")

</div>

Oh interesting. The reason for the two behaviors is because there are two implementations:

1. An optimized implementation just for `Array` that avoids the scalar getindex and just copies the chunk of memory
2. The generic implementation for all `AbstractArray` that just uses repeated scalar getindex to move elements to a new array one at a time.

When you hit (1) you can effectively select `#undef` elements but when those methods don’t exist then you hit (2) and end up dereferencing an `#undef`.

An even more compelling set of examples is:

```julia
julia> v = Vector{Any}(undef, 4);

julia> v[1:2]
2-element Array{Any,1}:
 #undef
 #undef

julia> v[[1,2]]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex at ./array.jl:728 [inlined]
 [2] macro expansion at ./multidimensional.jl:699 [inlined]
 # ...

julia> v[1:1:2]
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex at ./array.jl:728 [inlined]
 [2] getindex(::Array{Any,1}, ::StepRange{Int64,Int64}) at ./array.jl:753
 [3] top-level scope at REPL[19]:1

```

I suppose those optimizations could/should check to see if the elements are defined — or perhaps only apply for concrete element types — but unfortunately that would then destroy the optimization!

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [June 19, 2019, 3:49pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/3 "2019-06-19T15:49:22Z")

</div>

I would rather expect the default (unoptimized) method to check if the value is defined and only copy it when it is defined.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [June 19, 2019, 3:59pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/4 "2019-06-19T15:59:04Z")

</div>

We don’t have an efficient way to generically ask if a given index is `#undef`, unfortunately. The current implementation [leaves a bit to be desired](https://github.com/JuliaLang/julia/blob/863e03fbb1e765b5ee48e74a7938d78db13bcada/base/abstractarray.jl#L403-L414)…

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [June 19, 2019, 5:35pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/5 "2019-06-19T17:35:21Z")

</div>

Thank you.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [June 20, 2019, 6:00am UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/6 "2019-06-20T06:00:40Z")

</div>

> [@mbauman](#):
>
> I suppose those optimizations could/should check to see if the elements are defined — or perhaps only apply for concrete element types — but unfortunately that would then destroy the optimization!

I think that for `#undef`, it is perfectly fine to have the _consequences of access undefined_, which would allow the current status quo or various similar optimizations in the future.

IMO the first thing you do with an array of `#undef` is to fill it, before anything else. They should not be passed around uninitialized to functions where elements can potentially be accessed. If initialization is deferred for some reason, `Union{Nothing,...}` is usually a much better choice.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [June 20, 2019, 2:03pm UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/7 "2019-06-20T14:03:56Z")

</div>

I really appreciate that @bkamins goes through and finds behaviors like this with such a fine tooth comb. It’s typically not because that’s what he does or because he wants some behavior, but rather it’s because he’s working on DataFrames’ behaviors and is very carefully considering their behaviors and how they match base Julia’s.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [June 21, 2019, 10:01am UTC](https://discourse.julialang.org/t/subsetting-uninitialized-arrays/25449/8 "2019-06-21T10:01:12Z")

</div>

Yes, I also like learning about these corner cases. For `DataFrame`, I would suggest that either

1. consequences are undefined when the arguments it was intialized with `#undef` in them,

2. test for this in the constructor (for concrete bits types, `isassigned` is a no-op and thus costless).

(1) is fast and consistent with the rest of Julia, (2) is excessively user-friendly.
