My problem occured while trying to write an efficient iterator for permutations groups: they can be efficient generated by running throught the products of some lists of permutations (some transversals).

I give here a simple MWE which mimics that situation, using concatenation of strings instead of multiplication of permutations to mimic a non-commutative product.

So imagine that a group is:

```
struct Group
s::Vector{String}
end
G=Group(["one","happy","man"])
```

and the â€śelementsâ€ť of `G`

are all the words made by taking one letter from the first string, one from the second, etcâ€¦

I can make an efficient iterator for this

```
I=(prod(x) for x in Iterators.product(G.s...));
```

and the timing is not bad.

```
julia> @btime collect(I)
902.024 ns (46 allocations: 1.84 KiB)
3Ă—5Ă—3 Array{String,3}:
[:, :, 1] =
"ohm" "oam" "opm" "opm" "oym"
"nhm" "nam" "npm" "npm" "nym"
"ehm" "eam" "epm" "epm" "eym"
[:, :, 2] =
"oha" "oaa" "opa" "opa" "oya"
"nha" "naa" "npa" "npa" "nya"
"eha" "eaa" "epa" "epa" "eya"
[:, :, 3] =
"ohn" "oan" "opn" "opn" "oyn"
"nhn" "nan" "npn" "npn" "nyn"
"ehn" "ean" "epn" "epn" "eyn"
```

But now I would like `G`

itself to be able to iterate. I do not want to write `for s in I`

or `for s in iterator(G)`

but `for s in G`

. So I want `G`

itself to iterate through `I`

.

The only way I found is:

```
Base.length(G::Group)=prod(length.(G.s))
Base.eltype(::Type{Group})=String
function Base.iterate(G::Group)
I=(prod(x) for x in Iterators.product(G.s...))
p=iterate(I)
if isnothing(p) return end
str,state=p
str,(I,state)
end
function Base.iterate(G::Group,(I,state))
p=iterate(I,state)
if isnothing(p) return end
str,state=p
str,(I,state)
end
```

This iterates OK but the performance is terrible:

```
julia> @btime collect(G);
5.672 ÎĽs (241 allocations: 13.92 KiB)
```

So my question is: is there a better way to do that, that is to delegate efficiently iteration from `G`

to a dynamically computed `I`

?