# Meaning and alternatives to "undef" when initializing vectors

It is not that I have problems using this, but particularly for didactic purposes I feel I need a clarification:

Whenever I initialize a vector of, lets say, integers, using, for example

``````x = Vector{Int64}(undef,3)
``````

There seems to be no other option to be put in the place of `undef`. I understand what `undef` is, but the syntax seems to suggest that something else could be used there to initialize the vector with specific values.

Thus, I have two questions:

1. In the initialization of numerical arrays (at least), that syntax accepts anything else in the place of `undef`? If so, what?
2. If not, is there any profound reason to maintain the syntax with that redundancy? Could it be adapted to accept, for example, `Vector{Int64}( index -> f(index), 3 )` to initialize a vector with a specific function of the indexes of the vector or anything else?

Just to clarify, I do not think that any of that would be needed. I am more concerned in understanding the reason behind that syntax, perhaps to explain to students.

Alternatively, wouldn’t be nice to have the possibility of initializing an array of `undef` values using something like

``````x = undef(Float64,3)
``````

that would look consistent with the `zeros(3)` and `ones(3)` options.

1 Like

The only other option I know of in Base is `I`:

``````julia> Matrix{Float64}(I, 3, 3)
3×3 Array{Float64,2}:
1.0  0.0  0.0
0.0  1.0  0.0
0.0  0.0  1.0
``````

Edit: You need `using LinearAlgebra` to get `I`

2 Likes

Oh, looking at `methods(Matrix{Float64})`, it looks like you can use `missing` as an initializer:

``````julia> Matrix{Union{Float64, Missing}}(missing, 3, 3)
3×3 Array{Union{Missing, Float64},2}:
missing  missing  missing
missing  missing  missing
missing  missing  missing
``````

and likewise with `nothing`.

2 Likes

Yes, but in that case we have to add the `Union{}` stuff there. It is a very niche use, I think (I’ve never seen the use of that in numerical computing).

Didn’t know of that, and, in any case, it doesn’t work here ``````julia> Matrix{Float64}(I, 3, 3)
ERROR: UndefVarError: I not defined

``````

You need

``````using LinearAlgebra
``````

to import `I`.

2 Likes

And what kind of stuff is `I`? meaning, how to implement something else if we wanted to?

``````julia> typeof(I)
UniformScaling{Bool}
``````

Try `@edit Matrix{Float64}(I, 3, 3)` and you’ll see that there’s nothing special about `I` in particular, except that someone has gone ahead and implemented:

``````## Matrix construction from UniformScaling
function Matrix{T}(s::UniformScaling, dims::Dims{2}) where {T}
A = zeros(T, dims)
v = T(s.λ)
for i in diagind(dims...)
@inbounds A[i] = v
end
return A
end
Matrix{T}(s::UniformScaling, m::Integer, n::Integer) where {T} = Matrix{T}(s, Dims((m, n)))
``````

You can do exactly the same thing: define some `struct MyCustomInitializer ...` and then implement `Matrix{T}(::MyCustomInitializer, ...)` to do whatever behavior you want to provide.

6 Likes

I is a struct designed to behave like an identity matrix of whatever size is needed in context. You would implement it by making a strut that stores no data, and has correctly implemented routines for all the operations you wanted it to support.

1 Like

That clarifies a lot. Thank you.

But would it make sense to let

``````Array{Int, 2}(5, 3, 3)
``````

behave like `fill(5, 3, 3)`? It just seems like `undef` and `I` and `missing` are special-cased, and I don’t understand why it doesn’t work for ‘everything’?

See issue:

4 Likes