Why the 1x1 matrix [2] is printed [2;;]?

Hello,

julia> x = repeat([2], 1, 1)
1x1 Matrix{Int64}:
 2

julia> print(x)
[2;;]

Why [2;;]?

julia> typeof([2])
Vector{Int64} (alias for Array{Int64, 1})

julia> typeof([2;;])
Matrix{Int64} (alias for Array{Int64, 2})

If you were to write it as [2], it would be a Vector of size (1,). It’s necessary to write it was [2;;] to form a Matrix with size (1,1). It’s printed this way so that it can be re-parsed accurately.

It seems you might have preferred [2] in this case. Unfortunately, I don’t have the answer for how to achieve that except by checking for this special case explicitly.

4 Likes

Also for more context, Julia uses the ; to separate dimension in multidimensional arrays with more semicolons indicating higher dimensions. Since a Matrix is just a 2-d Array, there are two semicolons, one for each dimension.

1 Like

Another way to say the same thing:

julia> size([1; 2; 3]) 
(3,)
julia> size([1;; 2;; 3])
(1, 3)
julia> size([1;])
(1,)
julia> size([1;;])
(1, 1)

While not absolute, Julia does tend to support homoiconicity. The representation of the data structure is also how to type the data structure in the language.

There are a few different ways to “print” data structures in Julia.

julia> x = repeat([2], 1, 1)
1×1 Matrix{Int64}:
 2

julia> print(x)
[2;;]
julia> display(x)
1×1 Matrix{Int64}:
 2

julia> show(x)
[2;;]

julia> show(stdout, MIME"text/plain"(), x)
1×1 Matrix{Int64}:
 2

julia> [2;;] == x
true

If you are coming from MATLAB, this may be confusing since MATLAB drops singleton dimensions and also considers everything to be a matrix by default. Julia does not do this.

1 Like
julia> [1;]
1-element Vector{Int64}:
 1

julia> [1;;]
1×1 Matrix{Int64}:
 1

julia> [1;;;]
1×1×1 Array{Int64, 3}:
[:, :, 1] =
 1

julia> [1;;;;]
1×1×1×1 Array{Int64, 4}:
[:, :, 1, 1] =
 1

julia> [1;;;;;]
1×1×1×1×1 Array{Int64, 5}:
[:, :, 1, 1, 1] =
 1

julia> [1;;;;;;]
1×1×1×1×1×1 Array{Int64, 6}:
[:, :, 1, 1, 1, 1] =
 1

julia> [1;;;;;;;]
1×1×1×1×1×1×1 Array{Int64, 7}:
[:, :, 1, 1, 1, 1, 1] =
 1

julia> [1;;;;;;;;]
1×1×1×1×1×1×1×1 Array{Int64, 8}:
[:, :, 1, 1, 1, 1, 1, 1] =
 1

julia> [1;;;;;;;;;]
1×1×1×1×1×1×1×1×1 Array{Int64, 9}:
[:, :, 1, 1, 1, 1, 1, 1, 1] =
 1

julia> [1;;;;;;;;;;]
1×1×1×1×1×1×1×1×1×1 Array{Int64, 10}:
[:, :, 1, 1, 1, 1, 1, 1, 1, 1] =
 1

While it is unlikely you will live long enough to declare a 10-dimensional array using this syntax, it’s there just in case.

To understand why this syntax is here:

julia> [1; 2;; 3; 4]
2×2 Matrix{Int64}:
 1  3
 2  4

julia> [1 3; 2 4]
2×2 Matrix{Int64}:
 1  3
 2  4

julia> [1 3; 2 4;;; 5 7; 6 8]
2×2×2 Array{Int64, 3}:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 5  7
 6  8

julia> [1; 2;; 3; 4;;; 5; 6;; 7; 8]
2×2×2 Array{Int64, 3}:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 5  7
 6  8

julia> ([1; 2;; 3; 4;;; 5; 6;; 7; 8]...,)
(1, 2, 3, 4, 5, 6, 7, 8)
1 Like

What?

2 Likes

Must have been hand-edited output. Actual size is (1, 3).

1 Like

I wanted to confirm but I’m AFK, so I tried this online REPL and got an unexpected result :sweat_smile:

That’s an older Julia version.

3 Likes

Yep, this is why I don’t normally code on my phone.

Why is that? I run Julia on my phone all the time via termux. Because of this, I can run the latest version of Julia on my phone without relying on repl.it to update Julia to the latest version in order to take advantage of the latest features.

In this case, I can run Julia 1.8.3 on my phone to get the correct result.

julia> x = [1;; 2;; 3 ]
1×3 Matrix{Int64}:
 1  2  3

julia> size(x)
(1, 3)


edit: This is on-topic because this original poster’s behavior depends on running a recent version of Julia. Other posters have commented they could not reproduce the behavior on their phone since they can only access older versions of Julia online. I am demonstrating how to run recent versions of Julia on a phone and provided a mechanism to do so.

1 Like

If only I could run Julia on my iPad :sweat_smile:

1 Like