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.

- 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)
```

- 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