# length(Iterators.flatten(...)) not working

**URL:** <https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 6, 2019, 6:28pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846 "2019-04-06T18:28:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [April 6, 2019, 6:28pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/1 "2019-04-06T18:28:04Z")

</div>

using julia 1.1.0 the example taken from the documentation [Iteration utilities · The Julia Language](https://docs.julialang.org/en/v1/base/iterators/#Base.Iterators.flatten) works, however while `collect` works, `length` throughs an error

```julia
julia> collect(Iterators.flatten((1:2, 8:9)))
4-element Array{Int64,1}:
 1
 2
 8
 9

julia> length(Iterators.flatten((1:2, 8:9)))
ERROR: ArgumentError: Iterates of the argument to Flatten are not known to have constant length
Stacktrace:
 [1] flatten_length(::Base.Iterators.Flatten{Tuple{UnitRange{Int64},UnitRange{Int64}}}, ::Type) at .\iterators.jl:892
 [2] length(::Base.Iterators.Flatten{Tuple{UnitRange{Int64},UnitRange{Int64}}}) at .\iterators.jl:894
 [3] top-level scope at none:0

```

I guess this is a bug, isn’t it?

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [April 6, 2019, 6:31pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/2 "2019-04-06T18:31:11Z")

</div>

adding

```julia
Base.length(f::Base.Iterators.Flatten{<:NTuple{N, Any}}) where N = sum(length, f.it)

```

fixes this for me, but maybe it is better to use generated function here?

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [April 6, 2019, 6:46pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/3 "2019-04-06T18:46:34Z")

</div>

or even more general fallback

```julia
Base.length(f::Iterators.Flatten) = sum(length, f.it)

```

I would actually go with this one, is there a reason this is not in Base.Iterators already?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 6, 2019, 6:48pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/4 "2019-04-06T18:48:51Z")

</div>

Not sure, probably just an oversight. I would open an issue or a PR about adding it.

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [April 6, 2019, 6:49pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/5 "2019-04-06T18:49:38Z")

</div>

good to hear, can you point me to where to open the issue/PR? thanks a lot!

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [April 6, 2019, 6:50pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/6 "2019-04-06T18:50:58Z")

</div>

> **[GitHub - JuliaLang/julia: The Julia Programming Language](https://github.com/JuliaLang/julia)**
>
> The Julia Programming Language. Contribute to JuliaLang/julia development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [April 6, 2019, 7:45pm UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/7 "2019-04-06T19:45:17Z")

</div>

Not all Flatten iterators should have their length known,  
only if all the iterators being flattened have known length does the overall have known length.

But in your example, that is indeed the case so it should work.

Here is the code from te old version of IterTools for `chain`, which has now been replaced by `flatten` in `Base`.

> <https://github.com/JuliaCollections/IterTools.jl/blob/v0.2.1/src/IterTools.jl#L197-L199>

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [April 7, 2019, 8:49am UTC](https://discourse.julialang.org/t/length-iterators-flatten-not-working/22846/8 "2019-04-07T08:49:14Z")

</div>

The question is whether we want length defined when it’s not O(1). See for example this [PR](https://github.com/JuliaLang/julia/pull/22691) which very conservatively added `length` for a couple of cases where the element type of the flattened iterator are known statically.

For your example of a tuple of ranges, I would say it’s fine to add `length` as tuples are never too long in practice, but for e.g. `Vector{<:Range}`, I don’t know. For example we have `BitSet` with O(n) length, so why not iterators?
