A type of collection inside ()

We know array comprehension, for example

temp = [i for i in collect(1:3)]

Instead of brackets I now use parentheses:

temp = (i for i in collect(1:3))

This is not a tuple, so temp[1] cannot be called. Its type is “Base.Generator{Vector{Int64}, typeof(identity)}”. Yet, 2 in temp can be called. Do such objects have a special name and uses?

They are called “generators” (Multi-dimensional Arrays · The Julia Language).
You can see it as a generic iterable collection with strictly sequential access (therefore, no indexing, but checking the presence of an element is possible by a linear search).

1 Like

Also note that you don’t need to collect the range:

julia> (i for i ∈ 1:3)
Base.Generator{UnitRange{Int64}, typeof(identity)}(identity, 1:3)

julia> 2 ∈ ans
true

Iterators are useful and performant and as a rule of thumb you shouldn’t collect them unless you absolutely have to, as that’s bad for performance.

2 Likes

It’s particularly undesirable here, @Mastomaki, since generators are ‘lazy’ constructs, it sort of ruins the point to eagerly collect a lazy collection inside a lazy generator:

julia> @btime (i for i in collect(1:1000));  # takes quite a bit of time
  525.758 ns (1 allocation: 7.94 KiB)

julia> @btime (i for i in (1:1000));  # takes no time at all
  1.100 ns (0 allocations: 0 bytes)

Actually, in your particular example, you wouldn’t need the generator at all, you would just directly write

temp = 1:3