```
for (i, j) in CartesianIndices(a)
println(i, j)
end
```

produces an error:

```
ERROR: iteration is deliberately unsupported for CartesianIndex. Use `I` rather than `I...`, or use `Tuple(I)...`
```

This is an unreasonable design of the Julia interface in my opinion, which implements unpacking using iterator. I suggest Julia have an additional function `unpack`

which is called when unpacking syntax is used and only falls back to `iterate`

by default.

1 Like

Take this:

```
for (i, j) in Tuple.(CartesianIndices(a))
println(i, j)
end
```

2 Likes

While the wording of this suggestion is rather forceful, there is merit to it, I think.

1 Like

It was using `map`

to get around this. Thanks

Note that this (and equivalent `map`

version) are allocating because they materialize a vector of tuples.

Compare with a non-allocating alternative (`unpack2`

below) which runs about 7x faster on my machine.

```
function unpack1(dims)
s = 0
for (i, j) in Tuple.(CartesianIndices(dims))
#println(i, j)
s += i + j
end
return s
end
function unpack2(dims)
s = 0
for ci in CartesianIndices(dims)
i, j = Tuple(ci)
#println(i, j)
s += i + j
end
return s
end
```

```
using BenchmarkTools
const dims = (1000, 1000)
@btime unpack1($dims)
@btime unpack2($dims)
```

Apparently, iteration of a `CartesianIndex`

is disabled to avoid a possible performance trap when splatting a `CartesianIndex`

. See #23719

If you want to live dangerously, you could define iteration on `CartesianIndex`

yourself.

This version (`unpack3`

below) is also non-allocating, and is also ~7x faster than the â€śmaterializingâ€ť version.

```
Base.iterate(ci::CartesianIndex) = iterate(Tuple(ci))
Base.iterate(ci::CartesianIndex, state) = iterate(Tuple(ci), state)
function unpack3(dims)
s = 0
for (i, j) in CartesianIndices(dims)
#println(i, j)
s += i + j
end
return s
end
```

In this case, a generator expression also works well (although in general generators sometimes are way slower due to type-problems), see:

```
julia> function unpack4(dims)
s = 0
for (i,j) in (Tuple(c) for c in CartesianIndices(dims))
s += i + j
end
return s
end
```

which on my system is as fast as `unpack2`

.

1 Like

I thought `map`

returns a generator, which is how python works. It turns out to return a vector.

Depending on the situation, eager operations is usually more efficient that lazy ones if everything fits into the memory. Iâ€™m not sure why in this case it is slower.