# Collect(a) vs. [a;]

Hi,
I donβt get the difference between `collect(a)` and `[a;]` for ranges.

``````julia> typeof(collect(5:7)) === typeof([5:7;])
true

julia> collect(5:7) == [5:7;]
true

julia> collect(5:7)
3-element Array{Int64,1}:
5
6
7

julia> [5:7;]
3-element Array{Int64,1}:
5
6
7
``````

Yet

``````julia> collect(5:7) === [5:7;]
false
``````

Is it only because:

``````julia> @which [5:7;]
vcat(rs::AbstractRange{T}...) where T in Base at range.jl:911

julia> @which collect(5:7)
collect(r::AbstractRange) in Base at range.jl:925
``````

Or maybe I just misunderstood `===`.

Moreover, for:

``````julia> A = Dict([5 => 2, 12 => 9])
Dict{Int64,Int64} with 2 entries:
5  => 2
12 => 9

julia> B = keys(A)
Base.KeySet for a Dict{Int64,Int64} with 2 entries. Keys:
5
12
``````

I expected `[B;]` to return the same as `collect(B)` yet it doesnβt:

``````julia> [B;]
1-element Array{Base.KeySet{Int64,Dict{Int64,Int64}},1}:
[5, 12]
``````

Is there a reason for that behavior?
Thanks in advance!
RΓ©mi

EDIT:
It seems to do exactly the same. I will take a look at the function definition.

``````julia> @benchmark collect(i:j) setup=((i,j)=(rand(1:100), rand(1:100)))
BenchmarkTools.Trial:
memory estimate:  80 bytes
allocs estimate:  1
--------------
minimum time:     35.413 ns (0.00% GC)
median time:      45.078 ns (0.00% GC)
mean time:        79.823 ns (26.02% GC)
maximum time:     50.168 ΞΌs (99.50% GC)
--------------
samples:          10000
evals/sample:     993

julia> @benchmark [i:j;] setup=((i,j)=(rand(1:100), rand(1:100)))
BenchmarkTools.Trial:
memory estimate:  80 bytes
allocs estimate:  1
--------------
minimum time:     35.374 ns (0.00% GC)
median time:      45.647 ns (0.00% GC)
mean time:        79.846 ns (25.69% GC)
maximum time:     50.445 ΞΌs (99.76% GC)
--------------
samples:          10000
evals/sample:     993
``````

I start with the easy one:

Yes I think so, e.g.:

``````julia> [5,6,7]==[5,6,7]
true

julia> [5,6,7]===[5,6,7]
false

help?> ===
search: === == !==

===(x,y) -> Bool
β‘(x,y) -> Bool

Determine whether x and y are identical, in the sense that no program could distinguish them. First the types of x and y are compared. If those are identical, mutable
objects are compared by address in memory and immutable objects (such as numbers) are compared by contents at the bit level. This function is sometimes called "egal". It
always returns a Bool value.

julia> ismutable([5,6,7])
true
``````

Array are mutable objects and are therefore compared by address in memory. Thats why above `===` comparison gives false.

4 Likes

Of course! Thatβs a strange thing that I wanted `===` to be `==` + type equality

This answer my main question, thanks!

If the arguments inside the square brackets are separated by semicolons ( `;` ) or newlines instead of commas, then their contents are vertically concatenated together instead of the arguments being used as elements themselves.

``````julia> @code_lowered collect(5:7)
CodeInfo(
1 β %1 = Base.vcat(r)
βββ      return %1
)
``````

As you can see: `collect` in this case is just a `vcat`, so identical to `[5:7;]`.

1 Like

Ok, that makes sense!
It seems like `collect(a)` should be preferred over `[a;]`:

``````julia> @code_lowered [5:7;]
CodeInfo(
911 1 ββ       Core.NewvarNode(:(a))                                                                                                                                                                   β
β          Core.NewvarNode(:(i))                                                                                                                                                                   β
β          Core.NewvarNode(:(#temp#@_7))                                                                                                                                                           β
β    %4  = (Base.convert)(Base.Int, 0)                                                                                                                                                             β
β          n = (Core.typeassert)(%4, Base.Int)                                                                                                                                                     β
912 β    %6  = rs                                                                                                                                                                                      β
β          #temp#@_4 = (Base.iterate)(%6)                                                                                                                                                          β
β    %8  = #temp#@_4 === nothing                                                                                                                                                                   β
β    %9  = (Base.not_int)(%8)                                                                                                                                                                      β
ββββ       goto #4 if not %9                                                                                                                                                                       β
2 ββ %11 = #temp#@_4                                                                                                                                                                               β
β          ra@_13 = (Core.getfield)(%11, 1)                                                                                                                                                        β
β    %13 = (Core.getfield)(%11, 2)                                                                                                                                                                 β
913 β    %14 = n                                                                                                                                                                                       β
β    %15 = (Base.length)(ra@_13)                                                                                                                                                                   β
β    %16 = %14 + %15                                                                                                                                                                               β
β    %17 = (Base.convert)(Base.Int, %16)                                                                                                                                                           β
β          n = (Core.typeassert)(%17, Base.Int)                                                                                                                                                    β
β          #temp#@_4 = (Base.iterate)(%6, %13)                                                                                                                                                     β
β    %20 = #temp#@_4 === nothing                                                                                                                                                                   β
β    %21 = (Base.not_int)(%20)                                                                                                                                                                     β
ββββ       goto #4 if not %21                                                                                                                                                                      β
3 ββ       goto #2                                                                                                                                                                                 β
915 4 ββ %24 = (Core.apply_type)(Base.Vector, \$(Expr(:static_parameter, 1)))                                                                                                                           β
β          a = (%24)(Base.undef, n)                                                                                                                                                                β
916 β          i = 1                                                                                                                                                                                   β
917 β    %27 = rs                                                                                                                                                                                      β
β          #temp#@_7 = (Base.iterate)(%27)                                                                                                                                                         β
β    %29 = #temp#@_7 === nothing                                                                                                                                                                   β
β    %30 = (Base.not_int)(%29)                                                                                                                                                                     β
ββββ       goto #10 if not %30                                                                                                                                                                     β
5 ββ %32 = #temp#@_7                                                                                                                                                                               β
β          ra@_9 = (Core.getfield)(%32, 1)                                                                                                                                                         β
β    %34 = (Core.getfield)(%32, 2)                                                                                                                                                                 β
β    %35 = ra@_9                                                                                                                                                                                   β
β          #temp#@_8 = (Base.iterate)(%35)                                                                                                                                                         β
β    %37 = #temp#@_8 === nothing                                                                                                                                                                   β
β    %38 = (Base.not_int)(%37)                                                                                                                                                                     β
ββββ       goto #8 if not %38                                                                                                                                                                      β
6 ββ %40 = ra@_9                                                                                                                                                                                   β
β          ra@_12 = %40                                                                                                                                                                            β
β    %42 = #temp#@_8                                                                                                                                                                               β
β          x = (Core.getfield)(%42, 1)                                                                                                                                                             β
β    %44 = (Core.getfield)(%42, 2)                                                                                                                                                                 β
918 β          \$(Expr(:inbounds, true))                                                                                                                                                                β
β          (Base.setindex!)(a, x, i)                                                                                                                                                               β
β          val = x                                                                                                                                                                                 β
β          \$(Expr(:inbounds, :pop))                                                                                                                                                                β
β          val                                                                                                                                                                                     β
919 β          i = i + 1                                                                                                                                                                               β
β          #temp#@_8 = (Base.iterate)(%35, %44)                                                                                                                                                    β
β    %52 = #temp#@_8 === nothing                                                                                                                                                                   β
β    %53 = (Base.not_int)(%52)                                                                                                                                                                     β
ββββ       goto #8 if not %53                                                                                                                                                                      β
7 ββ       goto #6                                                                                                                                                                                 β
8 ββ       #temp#@_7 = (Base.iterate)(%27, %34)                                                                                                                                                    β
β    %57 = #temp#@_7 === nothing                                                                                                                                                                   β
β    %58 = (Base.not_int)(%57)                                                                                                                                                                     β
ββββ       goto #10 if not %58                                                                                                                                                                     β
9 ββ       goto #5                                                                                                                                                                                 β
921 10 β       return a                                                                                                                                                                                β
)

julia> @code_lowered collect(5:7)
CodeInfo(
925 1 β %1 = (Base.vcat)(r)                                                                                                                                                                            β
βββ      return %1                                                                                                                                                                                 β
)
``````

Or not!

``````julia> @code_lowered vcat(5:7)
CodeInfo(
911 1 ββ       Core.NewvarNode(:(a))                                                                                                                                                                   β
β          Core.NewvarNode(:(i))                                                                                                                                                                   β
β          Core.NewvarNode(:(#temp#@_7))                                                                                                                                                           β
β    %4  = (Base.convert)(Base.Int, 0)                                                                                                                                                             β
β          n = (Core.typeassert)(%4, Base.Int)                                                                                                                                                     β
912 β    %6  = rs                                                                                                                                                                                      β
β          #temp#@_4 = (Base.iterate)(%6)                                                                                                                                                          β
β    %8  = #temp#@_4 === nothing                                                                                                                                                                   β
β    %9  = (Base.not_int)(%8)                                                                                                                                                                      β
ββββ       goto #4 if not %9                                                                                                                                                                       β
2 ββ %11 = #temp#@_4                                                                                                                                                                               β
β          ra@_13 = (Core.getfield)(%11, 1)                                                                                                                                                        β
β    %13 = (Core.getfield)(%11, 2)                                                                                                                                                                 β
913 β    %14 = n                                                                                                                                                                                       β
β    %15 = (Base.length)(ra@_13)                                                                                                                                                                   β
β    %16 = %14 + %15                                                                                                                                                                               β
β    %17 = (Base.convert)(Base.Int, %16)                                                                                                                                                           β
β          n = (Core.typeassert)(%17, Base.Int)                                                                                                                                                    β
β          #temp#@_4 = (Base.iterate)(%6, %13)                                                                                                                                                     β
β    %20 = #temp#@_4 === nothing                                                                                                                                                                   β
β    %21 = (Base.not_int)(%20)                                                                                                                                                                     β
ββββ       goto #4 if not %21                                                                                                                                                                      β
3 ββ       goto #2                                                                                                                                                                                 β
915 4 ββ %24 = (Core.apply_type)(Base.Vector, \$(Expr(:static_parameter, 1)))                                                                                                                           β
β          a = (%24)(Base.undef, n)                                                                                                                                                                β
916 β          i = 1                                                                                                                                                                                   β
917 β    %27 = rs                                                                                                                                                                                      β
β          #temp#@_7 = (Base.iterate)(%27)                                                                                                                                                         β
β    %29 = #temp#@_7 === nothing                                                                                                                                                                   β
β    %30 = (Base.not_int)(%29)                                                                                                                                                                     β
ββββ       goto #10 if not %30                                                                                                                                                                     β
5 ββ %32 = #temp#@_7                                                                                                                                                                               β
β          ra@_9 = (Core.getfield)(%32, 1)                                                                                                                                                         β
β    %34 = (Core.getfield)(%32, 2)                                                                                                                                                                 β
β    %35 = ra@_9                                                                                                                                                                                   β
β          #temp#@_8 = (Base.iterate)(%35)                                                                                                                                                         β
β    %37 = #temp#@_8 === nothing                                                                                                                                                                   β
β    %38 = (Base.not_int)(%37)                                                                                                                                                                     β
ββββ       goto #8 if not %38                                                                                                                                                                      β
6 ββ %40 = ra@_9                                                                                                                                                                                   β
β          ra@_12 = %40                                                                                                                                                                            β
β    %42 = #temp#@_8                                                                                                                                                                               β
β          x = (Core.getfield)(%42, 1)                                                                                                                                                             β
β    %44 = (Core.getfield)(%42, 2)                                                                                                                                                                 β
918 β          \$(Expr(:inbounds, true))                                                                                                                                                                β
β          (Base.setindex!)(a, x, i)                                                                                                                                                               β
β          val = x                                                                                                                                                                                 β
β          \$(Expr(:inbounds, :pop))                                                                                                                                                                β
β          val                                                                                                                                                                                     β
919 β          i = i + 1                                                                                                                                                                               β
β          #temp#@_8 = (Base.iterate)(%35, %44)                                                                                                                                                    β
β    %52 = #temp#@_8 === nothing                                                                                                                                                                   β
β    %53 = (Base.not_int)(%52)                                                                                                                                                                     β
ββββ       goto #8 if not %53                                                                                                                                                                      β
7 ββ       goto #6                                                                                                                                                                                 β
8 ββ       #temp#@_7 = (Base.iterate)(%27, %34)                                                                                                                                                    β
β    %57 = #temp#@_7 === nothing                                                                                                                                                                   β
β    %58 = (Base.not_int)(%57)                                                                                                                                                                     β
ββββ       goto #10 if not %58                                                                                                                                                                     β
9 ββ       goto #5                                                                                                                                                                                 β
921 10 β       return a                                                                                                                                                                                β
)
``````

They are the same. Both is at the end `vcat`.

1 Like

Yeah, personally I would go for `collect`, since turning an iterable into a `Vector` (or more generally an `Array`) is exactly its purpose, so in my opinion the code is more readable that way. I wouldnβt really worry about comparing implementations unless it turned out to be a performance bottleneck (in which case you might want to avoid allocating arrays anyway, depending on the situation).

1 Like

I see it the same way. Actually I had to look up for the `[5:7;]` syntax because I wasnβt aware of this subtilty.

1 Like

I agree!
This notation is used in julia testings:
https://github.com/JuliaLang/julia/blob/46cf572773b05d8f4ab74705b139f7a921227c02/test/sorting.jl#L36

Code should ideally signal intent, not rely on a corner case. I think that `collect` is vastly preferable.

4 Likes

I also agree and opened an issue to suggest the change (https://github.com/JuliaLang/julia/issues/37698)

1 Like