# Vector vs n-element Vector?! Can push to one but not the other

**URL:** <https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080>\
**Category:** New to Julia\
**Tags:** question, array\
**Created:** [October 21, 2022, 7:16pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080 "2022-10-21T19:16:52Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![micampbell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/micampbell/32/43763_2.png) [@micampbell](https://discourse.julialang.org/u/micampbell)\
**Post date:** [October 21, 2022, 7:16pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/1 "2022-10-21T19:16:52Z")

</div>

Why is there a difference between a & b? Why can I push to a but not b?

> julia\> a = Real []  
> Real []

> julia\> push!(a, 0.0)  
> 1-element Vector{Real}:  
> 0.0

> julia\> b = Vector{Real}  
> Vector{Real} (alias for Array{Real, 1})

> julia\> push!(b, 0.0)  
> ERROR: MethodError: no method matching push!(::Type{Vector{Real}}, ::Float64)  
> Closest candidates are:  
> push!(::Any, ::Any, ::Any) at abstractarray.jl:3059  
> push!(::Any, ::Any, ::Any, ::Any…) at abstractarray.jl:3060  
> push!(::AbstractChannel, ::Any) at channels.jl:10  
> …

The type of a is a “1-element Vector{Real}”, whereas b is “Vector{Real} (alias for Array{Real, 1})”.

I understand that there is no clear way to push to a matrix, and so the latter issue makes sense, but what’s up with a? Why call it a vector, when it acts like a list? Wouldn’t the “1-element” part of the name imply that the size is fixed? The reality is the opposite.

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [October 21, 2022, 7:39pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/2 "2022-10-21T19:39:04Z")

</div>

`Vector{Real}` is a _type_, not an instance of that type. To construct an empty instance, use the zero-argument constructor.

```julia
julia> b = Vector{Real}()
Real[]

julia> push!(b, 0.0)
1-element Vector{Real}:
 0.0

```

Unlike in Matlab, a vector is not a matrix: the former has one dimension, the latter has two.

```julia
julia> Vector <: AbstractMatrix
false

```

…and a `Vector`’s length isn’t encoded in its type signature and is free to vary. StaticArrays.jl provides fixed-length vectors.

```julia
julia> dump(ones(3))
Array{Float64}((3,)) [1.0, 1.0, 1.0]

julia> dump(@SVector ones(3))
SVector{3, Float64}
  data: Tuple{Float64, Float64, Float64}
    1: Float64 1.0
    2: Float64 1.0
    3: Float64 1.0

```

---

<div class="post-metadata">

**Author:** ![micampbell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/micampbell/32/43763_2.png) [@micampbell](https://discourse.julialang.org/u/micampbell)\
**Post date:** [October 21, 2022, 7:44pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/3 "2022-10-21T19:44:02Z")

</div>

You have explained it very well. Thanks. I am only a casual Julia programmer - so coming from other languages - I’m used to the “new” keyword to trigger the constructor. Without it - I see that I am only making an alias for the type.  
So, generally the parameterless constructor is a function and requires the “()” for it to be invoked. Correct?

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [October 21, 2022, 7:57pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/4 "2022-10-21T19:57:28Z")

</div>

Constructors are just Julia functions and can, in principle, take any number of arguments. Multiple dispatch is used to resolve which type is constructed.

```julia
julia> methods(Vector)
# 5 methods for type constructor:
[1] (Vector)() in Base at baseext.jl:38
[2] (Vector)(x::SparseArrays.AbstractSparseVector{Tv}) where Tv in SparseArrays at C:\Users\alexa\.julia\juliaup\julia-1.8.2+0.x64\share\julia\stdlib\v1.8\SparseArrays\src\sparsevector.jl:947
[3] (Vector)(D::SuiteSparse.CHOLMOD.Dense{T}) where T in SuiteSparse.CHOLMOD at C:\Users\alexa\.julia\juliaup\julia-1.8.2+0.x64\share\julia\stdlib\v1.8\SuiteSparse\src\cholmod.jl:856
[4] (Array{T, N} where T)(x::AbstractArray{S, N}) where {S, N} in Core at boot.jl:481
[5] (Vector)(::UndefInitializer, m::Integer) in Base at baseext.jl:32

```

There’s special syntax for parameterless array constructors, but everything else should take the `T()` form.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [October 21, 2022, 8:41pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/5 "2022-10-21T20:41:23Z")

</div>

I just want to point out to the OP that most of the time you don’t want to use `Vector{Real}` because `Real` is an abstract type. Your vector `a` as you’ve defined it can hold any combination of `Float64`, `Integer`, `Float32`, etc. values and this comes at a cost in performance:

```julia
julia> x1 = Real[1.0 for _ in 1:1000];

julia> x2 = Float64[1.0 for _ in 1:1000]; # or just use ones(1000)

julia> using BenchmarkTools

julia> @btime reverse!($x1);
  880.952 ns (0 allocations: 0 bytes)

julia> @btime reverse!($x2);
  222.925 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 22, 2022, 7:38am UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/6 "2022-10-22T07:38:51Z")

</div>

Interesting that `reverse!` is also slower for Real, it shouldn’t have to be because for that operation you just need to reverse the list of pointers which are the same size as Float64 and stored contiguously as well. You don’t have allocations here which would happen if you stored any new values that need to be boxed somewhere on the heap. So it’s not the best example for showing that abstract element type containers are bad 🙂

---

<div class="post-metadata">

**Author:** ![micampbell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/micampbell/32/43763_2.png) [@micampbell](https://discourse.julialang.org/u/micampbell)\
**Post date:** [October 22, 2022, 6:05pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/7 "2022-10-22T18:05:31Z")

</div>

I’m happy to learn about performance improvements with better typing. I will try to keep that in mind. But, if I may return to the original problem that I faced.  
The feedback I received from REPL (or even in the variable watcher in VS code) could be clearer. Who do I suggest this to?  
The response for a is “Real []” - it’d be more informative (although perhaps a little verbose) to say “Object of type Real []”  
or better yet for b…instead of reporting “Vector{Real}”, it should be “DataType Vector{Real}”  
Of course, I could have debugged before my post by using “typeof()” and seeing that b is a DataType. but shouldn’t the responses in REPL just say this.  
In VS Code variable watcher, it shows a as “Vector{Real} with 0 elements” and b as “Vector{Real}”. That’s confusing right. Let’s change it to “DataType Vector{Real}”

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 22, 2022, 6:32pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/8 "2022-10-22T18:32:16Z")

</div>

> [@micampbell](#):
>
> Object of type Real

`Object of type Real[]` would not be accurate because the type is `Vector{Real}`, `Real[]` is just shortcut syntax for `Vector{Real}()` (note the parentheses).

I guess you kind of get used to it over time that instances of values usually have `(...)` in their printout because the representation looks like the instantiation syntax by default. That’s also the main reason against your suggestions like `DataType Vector{Real}`. It’s a feature that many values print in a way such that you can copy paste the printed representation, execute it, and get another object like that. `DataType Vector{Real}` would break that.

---

<div class="post-metadata">

**Author:** ![micampbell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/micampbell/32/43763_2.png) [@micampbell](https://discourse.julialang.org/u/micampbell)\
**Post date:** [October 22, 2022, 7:43pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/9 "2022-10-22T19:43:26Z")

</div>

sorry, but where are you seeing the parentheses when interrogating a variable?

---

<div class="post-metadata">

**Author:** ![micampbell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/micampbell/32/43763_2.png) [@micampbell](https://discourse.julialang.org/u/micampbell)\
**Post date:** [October 22, 2022, 8:01pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/10 "2022-10-22T20:01:02Z")

</div>

Yes, I’m pretty sure we don’t want parentheses when reporting the variable type. That would be referring to the function/constructor. For example, one could do this

> c = methods(Vector{Real})[1]  
> Vector{T}() where T in Core at boot.jl:478

Interestingly, when you interrogate with “typeof”, you simply get MethodList.

> julia\> typeof(c)  
> Base.MethodList

This further convinces me what is reported in the REPL listener and for VS variable watcher should match “typeof(b)”,that is, it should be “DataType” not “Vector{Real}”

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 22, 2022, 8:29pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/11 "2022-10-22T20:29:58Z")

</div>

I said the opposite, types don’t print with parentheses, instances of those types often do if that’s how you usually instantiate them.

---

<div class="post-metadata">

**Author:** ![yha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yha/32/3502_2.png) [@yha](https://discourse.julialang.org/u/yha)\
**Post date:** [October 22, 2022, 10:51pm UTC](https://discourse.julialang.org/t/vector-vs-n-element-vector-can-push-to-one-but-not-the-other/89080/12 "2022-10-22T22:51:39Z")

</div>

> [@micampbell](#):
>
> sorry, but where are you seeing the parentheses when interrogating a variable?

This is the default representation of objects:

```julia
julia> struct A{T}
           x::T
       end

julia> A(4)
A{Int64}(4)

```

An example from `Base`:

```julia
julia> Ref(3)
Base.RefValue{Int64}(3)

```

(here, `Ref` is an abstract type, but still has constructors which construct objects of an appropriate subtype)
