# Generator questions

While poking around with the generator example below to try understanding the concept, some questions popped up:

• Why is the last equality false given that the generator was regenerated?
• With the command `g.f(g.iter[n])`, are we materializing the nᵗʰ element of the generator?
``````A = [1 2; 3 4]
B = [A^i for i in 0:2]

g = (A*b for b in B)    # creates generator
G = collect(g)          # 3-element Vector{Matrix{Int64}}
g.f(g.iter[2]) == G[2]  # true
g.f(g.iter[3]) == G[3]  # true

g.iter[3] = ones(2,2)   # assigned to a different matrix here
g.f(g.iter[3]) == G[3]  # false (OK)
g = (A*b for b in B)    # re-creates generator
g.f(g.iter[2]) == G[2]  # true
g.f(g.iter[3]) == G[3]  # false (why does the previous assignment still stand?)
``````

Thank you.

Why is the last equality false given that the generator was regenerated?

As there is no copy for `B`. The generator `g` holds the original reference of the iterator here:

``````julia> objectid(g.iter)
0x35595f9c567dff49

julia> objectid(B)
0x35595f9c567dff49
``````

With the command `g.f(g.iter[n])` , are we materializing the nᵗʰ element of the generator?

Only for `(... for element in array)` it can be `true`, but in general it is not the case.

There are two counterexamples to your guess.

1. not all generators use the notion of “nᵗʰ element”:
``````julia> res = ( [i, j] for i = 1: 2, j = 1:2)
julia> n = 1; res.iter[1]

ERROR: MethodError: no method matching getindex(::Base.Iterators.ProductIterator{Tuple{UnitRange{Int64}, UnitRange{Int64}}}, ::Int64)
``````
1. we use the iterator interface to handle iterations. Random accessing is not available for iterables.
``````julia> using DataStructures
julia> xs = list(1, 2, 3)
list(1, 2, 3)

julia> g = (k * 2 for k in xs)
Base.Generator{Cons{Int64}, var"#17#18"}(var"#17#18"(), list(1, 2, 3))

julia> collect(g)
3-element Vector{Int64}:
2
4
6

g.iter[1]
ERROR: MethodError: no method matching getindex(::Cons{Int64}, ::Int64)
``````
2 Likes