# Should zipping with an infinite iterator preserve iterator shape?

**URL:** <https://discourse.julialang.org/t/should-zipping-with-an-infinite-iterator-preserve-iterator-shape/140009>\
**Category:** Internals & Design\
**Tags:** arrays, iterators, shapes, iterables\
**Created:** [October 13, 2026, 7:44pm UTC](https://discourse.julialang.org/t/should-zipping-with-an-infinite-iterator-preserve-iterator-shape/140009 "2026-10-13T19:44:57Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [October 13, 2026, 7:44pm UTC](https://discourse.julialang.org/t/should-zipping-with-an-infinite-iterator-preserve-iterator-shape/140009/1 "2026-10-13T19:44:57Z")

</div>

Currently, `Base.IteratorSize(zip(iterators...))` is never `Base.HasShape` when any iterator in `iterators` is infinite (when its `IteratorSize` is `Base.IsInfinite`). At best the `IteratorSize` is `HasLength`.

I feel it may make sense to preserve the iterator shape in some cases. For example, currently `Base.IteratorSize(zip(infinite_iterator, shapeful_iterator)) === Base.HasLength()`, however I feel like it may make more sense to have `Base.IteratorSize(zip(infinite_iterator, shapeful_iterator)) === Base.IteratorSize(shapeful_iterator)`.

Assuming an iterator with `IsInfinite` has no (implicit) shape, I feel that my proposal is a straightforward improvement. However, arguably someone could have written an iterator intended to be both infinite and shapeful. If that (hypothetical) Julia programmer has chosen give their infinite but shapeful iterator an `IteratorSize` of `IsInfinite`, my proposal being implemented could perhaps break their code. Not sure.

This issue raises a tangential matter: **Should an `IteratorSize` trait be added for iterators that are both shapeful and infinite?** Something like `IsInfiniteShapeful{N}`. Might be interesting for infinite arrays, such as in InfiniteArrays.jl.

A concrete motivating example for having `zip` preserve shape like described above is `enumerate`. `enumerate(x)` is very similar to `zip(Iterators.countfrom(), x)`. Basically the only difference is that `enumerate(x)` preserves the shape of `x`. If we made `zip(Iterators.countfrom(), x)` preserve the shape of `x`, the implementation of `enumerate` would not have to rely on the special type `Enumerate` any more, and `Enumerate` could be deleted. See PR [implement `Iterators.enumerate` in terms of `zip` and `countfrom` - Pull Request #63792 - JuliaLang/julia - GitHub](https://github.com/JuliaLang/julia/pull/63792) for the latter (closed pending on a decision possibly being reached in the discussion here).

For what that is worth, the second line here is the code responsible for the discussed behavior of `IteratorSize` on iterators obtained with `zip`, the shape not being preserved:

> <https://github.com/JuliaLang/julia/blob/503caaac8088e1a9107f8da3ead59f0e6ba0ff67/base/iterators.jl#L509-L510>
