# 1:n, (1:n)', and (1:n)''

Hello. I am curious about the following behavior of the transposition operator associated with the `UnitRange` data type. Let `n` be a natural number. Now, the type of `1:n` is `UnitRange{Int64}`.
But why does `(1:n)'` become a row vector (or more precisely, `Matrix{Int64}` type of size 1 x n) while `(1:n)''` become a column vector (or more precisely, ``Matrix{Int64}`type of size n x 1)? Why does the single transposition applied to`1:n``` turn it into a row vector? This behavior is mysterious to me.
Thanks!
BVPs

Iâ€™m happy to answer your questions here, but first Iâ€™m curious about your expectationsâ€¦ given `x = (1:n)'`, what kind of thing do you expect `x` to be? What kinds of operations do you want to perform on `x`?

If anything is mysterious then it is the fact that `(1:n)'` becomes a row vector. (i.e. that `1:n` is interpreted as a columns vector). But since a row vector is just a matrix, transposing it will remain a matrix; this seems very natural to me.

• `(1:n)'` returns a `1Ă—n` row-matrix because weâ€™ve chosen to treat one-dimensional arrays as though they are one-column matrices in many operations. This is actively a point of design and research â€” and possible change â€” which is why I wanted to hear about your expectations before explaining the current design. Itâ€™s a dense array of `Int`s because we donâ€™t have any specialized types that can more compactly represent ranges of size `1Ă—n`.

• The transpose of a `1Ă—n` row-matrix is a `nĂ—1` column-matrix. Conversely, the transpose of a `nĂ—1` column matrix is a `1Ă—n` row-matrix. This is a rather sensible definition of transpose. We donâ€™t want to do something special for dimensions that happen to be one because that would be type-unstable (returning either a one- or two-dimensional container depending upon the size of the argument).

These two choices lead directly to the relatively unsatisfactory result that the double transpose of a one-dimensional array is not equal to itself (`v != v''`). Thereâ€™s lots more you can read here if youâ€™re interested.

Thanks for your quick reply! In MATLAB `x=1:n` is simply a row vector (i.e., a matrix of size 1 x n). But, since julia is not MATLAB, I cannot expect that happens. Hence, most naturally, I want to see `x=1:n` as a `Vector{Int64}`. My guess is that `UnitRange{Int64}` is a specialization of `Vector{Int64}`. Correct me if I am wrong. Suppose this is true. Then, why the transposition of the `Vector` data turns into a row vector? Is this because a `Vector` data type is weakly viewed as a column vector? Or is it truly a column vector?

Thanks for your explanation! I now understand that itâ€™s a touchy issue. In particular, the fact `v != v''` may invite a potential problem eventually.

Yup, a lot of this falls out from the fact that Matlabâ€™s behaviors donâ€™t mesh well with a stronger type system that differentiates scalars from one-dimensional containers and two-dimensional containers. In fact, even scalars in Matlab are implicitly 1x1 matrices:

``````>> x = 1;
x(end+1) = 2;
x
x =
1     2

>> x(end+1, :) = [3,4]
x =
1     2
3     4
``````

There are some surprising indexing rules in Matlab because of this, â€śiterationâ€ť is bizarre, and `length` is really quite strange, but for the most part it works surprisingly well.

In Julia, we have completely separate behaviors for scalars and arrays. This choice is a key advantage for the compiler and allows Julia to perform much more aggressive optimizations. We even have different behaviors for one-dimensional and two-dimensional arrays, because the former allow for efficiently push!-ing and pop!-ing elements. Changing the size of a two-dimensional array requires copying memory in many cases.

2 Likes