How to efficiently create a vector from a matrix comprehensions?

Since v0.5 comprehensions are shape-preserving (0.5-style comprehensions by JeffBezanson · Pull Request #16622 · JuliaLang/julia · GitHub), so

m = [x for x in [1 2; 3 4]]

results in a matrix.

How should one, using a comprehension, create a vector instead? Something that better reflects a traditional for loop:

v = Int[]
for x in [1 2; 3 4]
    push!(v, x)
end

Preferably in an efficient way, with no temporaries.

m = [x for x in vec([1 2; 3 4])]? vec just uses a view and does’t copy.

It doesn’t seem so:

julia> typeof(vec([1 2; 3 4]))
Array{Int64,1}

That’s not testing anything. Arrays are views too.

julia> const v = [1 2;3 4]
2×2 Array{Int64,2}:
 1  2
 3  4

julia> @time vec(v)
  0.000001 seconds (6 allocations: 240 bytes)
4-element Array{Int64,1}:
 1
 3
 2
 4

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

julia> @time vec(w)
  0.000002 seconds (6 allocations: 240 bytes)
12-element Array{Int64,1}:
 1
 3
 2
 4
 3
 7
 4
 7
 5
 8
 6
 9

julia> z = vec(w)
12-element Array{Int64,1}:
 1
 3
 2
 4
 3
 7
 4
 7
 5
 8
 6
 9

julia> z[1] = 10
10

julia> w
2×6 Array{Int64,2}:
 10  2  3  4  5  6
  3  4  7  7  8  9


No allocations, just the allocation of the view which is constant 240 bytes. The array just tells it how to index. Once Tim Holy explained that, the magic went away.

Wow! That is something completely new to me! And, at a first sight, this kind of hidden aliasing seems a little bit too dangerous…

Thanks @ChrisRackauckas.

By the way, besides that comment by @tim.holy, is there any documentation on this?

vec really doesn’t copy:

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

julia> v = vec(A)
4-element Array{Int64,1}:
 1
 3
 2
 4

julia> A[1,1] = 11
11

julia> v
4-element Array{Int64,1}:
 11
  3
  2
  4