`peek` seems to consume iterator elements?

using Base.Iterators

a = collect("abbcccddddeeeee")
b = Base.Iterators.Stateful(a)

while !isempty(b)
    c = peek(b)
    println(collect(takewhile(x -> x == c, b)))
end

I’m trying to learn about Julia stateful iterators, and tried out the above code. I was expecting to see printed out ['a'] on a line by itself, ['b', 'b'] on a line by itself, etc., however, what I got out was:

['a']
['b']
['c', 'c']
['d', 'd', 'd']
['e', 'e', 'e', 'e']

It would seem that the peek call didn’t consume an iterator element the first time around, but did consume an element every time after that?

I think it is due to takewhile, not peek:

Oh … I guess I was expecting something similar to Racket’s takef function (i.e. doesn’t consume first non-matching).

Is there a different iterator constructor in Julia that I could use that would not have the “consume first non-matching” behavior?

My understanding is that this behavior is not exactly desirable; it may even be a bug. So I don’t think there is a takewhile for stateful iterators that doesn’t consume the first non-matching element.

One way around is to implement the behavior yourself. For example, the following should give you what you expected:

julia> while !isempty(b)
           c = peek(b)
           xs = []
           while !isempty(b) && peek(b) == c
               push!(xs, popfirst!(b))
           end
           println(xs)
       end

Yours is more elegant than mine, but that is what I had come up with.