Functions copyto! and splat don't work with arrays with #undef 'values'

The copyto!() function and splat(…) are unable to handle arrays with uninitialized values.

Is this supposed to not work or reasons I’m not seeing, or should this be fixable?

Here is an example:

julia> a = Array{String}(undef, 3)
3-element Array{String,1}:
 #undef
 #undef
 #undef

julia> a[1] = "a"
"a"

julia> b = Array{Any}(undef, 3)
3-element Array{Any,1}:
 #undef
 #undef
 #undef

julia> copyto!(b,a)
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex at ./array.jl:729 [inlined]
 [2] copyto!(::IndexLinear, ::Array{Any,1}, ::IndexLinear, ::Array{String,1}) at ./abstractarray.jl:753
 [3] copyto!(::Array{Any,1}, ::Array{String,1}) at ./abstractarray.jl:745
 [4] top-level scope at none:0

julia> print(a...)
ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] top-level scope at none:0

You cannot assign #undef to something so the behavior for copyto! looks correct.

For the splatting, you are effectively trying to do print(a[1], a[2], a[3]) which accesses the #undef and thus errors.

What would the “fix” here be? #undef is not a first class value in Julia.

1 Like

Should have mentioned what the fixes would be.

for copyto!
it would copy the data in the array, and skip over the undef values:

julia> a = Array{String}(undef, 3)
3-element Array{String,1}:
 #undef
 #undef
 #undef

julia> a[2] = "a"
"a"

julia> a
3-element Array{String,1}:
 #undef
    "a"
 #undef

julia> b = Array{Any}(undef, 3)
3-element Array{Any,1}:
 #undef
 #undef
 #undef

julia> copyto!(b,a)
3-element Array{String,1}:
 #undef
    "a"
 #undef

This might make more sense in the context of the BSON library and issue https://github.com/MikeInnes/BSON.jl/issues/43 and pull request https://github.com/MikeInnes/BSON.jl/pull/47

We were able to work around it (there were issues with saving trained flux models) and these issues would make saving and reading partial arrays a lot easier.

for print(a…):

julia> print(a...)
#undefa#undef

more particularly for function calls

julia> f(a...) = print(a...)
f (generic function with 1 method)

julia> f(a)
[#undef, "a", #undef]
1 Like

That would be surprising to me, and might hide bugs in the code.

Yeah, I think explicitly handling #undef when needed is the way to go.

#undef is just the way that arrays and structs decide to print their non assigned elements. There is no way to have an object that is #undef so you can’t even write the print function you envision.

2 Likes

Alright, that makes sense.

Thanks for the responses.