# Why does stateful iterators restrict length to \`Signed\`?

**URL:** https://discourse.julialang.org/t/why-does-stateful-iterators-restrict-length-to-signed/93263
**Category:** Internals & Design
**Tags:** iterators
**Created:** [January 20, 2023, 12:55pm UTC](https://discourse.julialang.org/t/why-does-stateful-iterators-restrict-length-to-signed/93263 "2023-01-20T12:55:07Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [January 20, 2023, 12:55pm UTC](https://discourse.julialang.org/t/why-does-stateful-iterators-restrict-length-to-signed/93263/1 "2023-01-20T12:55:07Z")

</div>

`Iterators.Stateful` has the definition

```julia
mutable struct Stateful{T, VS, N<:Integer}
    itr::T
    # A bit awkward right now, but adapted to the new iteration protocol
    nextvalstate::Union{VS, Nothing}

    # Number of remaining elements, if itr is HasLength or HasShape.
    # if not, store -1 - number_of_consumed_elements.
    # This allows us to defer calculating length until asked for.
    # See PR #45924
    remaining::N
    @inline function Stateful{<:Any, Any}(itr::T) where {T}
        itl = iterlength(itr)
        new{T, Any, typeof(itl)}(itr, iterate(itr), itl)
    end
    @inline function Stateful(itr::T) where {T}
        VS = approx_iter_type(T)
        itl = iterlength(itr)
        return new{T, VS, typeof(itl)}(itr, iterate(itr)::VS, itl)
    end
end

```

In the constructor, it calls

```julia
function iterlength(it)::Signed
    if IteratorSize(it) isa Union{HasShape, HasLength}
       return length(it)
    else
        -1
    end
end

```

but what’s the point of this `Signed` restriction? Subtypes of `Integer` that aren’t subtypes of `Signed` are ruled out as the length. For example, this doesn’t work:

```julia
julia> using Infinities

julia> x = 1:∞
1:∞

julia> Iterators.Stateful(axes(x,1))
ERROR: MethodError: no method matching Signed(::InfiniteCardinal{0})

Closest candidates are:
  (::Type{T})(::T) where T<:Number
   @ Core boot.jl:792
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
   @ Base char.jl:50
  (::Type{T})(::Base.TwicePrecision) where T<:Number
   @ Base twiceprecision.jl:266
  ...

Stacktrace:
 [1] convert(#unused#::Type{Signed}, x::InfiniteCardinal{0})
   @ Base ./number.jl:7
 [2] iterlength(it::InfiniteArrays.OneToInf{Int64})
   @ Base.Iterators ./iterators.jl:1413
 [3] Base.Iterators.Stateful(itr::InfiniteArrays.OneToInf{Int64})
   @ Base.Iterators ./iterators.jl:1406
 [4] top-level scope
   @ REPL[47]:1

```

The fact that this is infinite is a red herring, as this would rule out static integers and such as well.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [January 20, 2023, 2:46pm UTC](https://discourse.julialang.org/t/why-does-stateful-iterators-restrict-length-to-signed/93263/2 "2023-01-20T14:46:59Z")

</div>

That’s an assertion, declaring something about a value, not a type restriction for method signatures.

As for the branch you pasted above, note that the [iteration interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration) distinguishes finite and infinite iterators (and those with unknown length). For `Union{HasShape, HasLength}`, the length should really be finite.

---

<div class="post-metadata">

### Author: ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)
#### Post date: [January 20, 2023, 2:56pm UTC](https://discourse.julialang.org/t/why-does-stateful-iterators-restrict-length-to-signed/93263/3 "2023-01-20T14:56:53Z")

</div>

I understand that it’s a conversion, which will fail in general for subtypes of `Integer` that don’t define a method for `Signed`. Also, I was merely looking for an example of an `Integer` that isn’t a subtype of `Signed` and can’t be converted to one. This doesn’t need to be infinite, as in the example.
