Proposal for a channel iterator for Crystal (insured by Go)

The aim is to emulate the very handy Go construct:

for i := range(c1) {
    // Do something with i
}
# Channel Iterator
def channel_each (c1, f)
    loop do
        if i = c1.receive?
            f.call(i)
        else 
            break
        end
    end 
end

c1 = Channel(Int32).new
c2 = Channel(Nil).new

# sender
spawn do
    (1..10).each do |i|
        sleep(100.milliseconds)
        c1.send(i)
    end
    c1.close
    c2.send nil
end

# receiver
spawn do
    channel_each c1,  ->(i : Int32) {
        puts i
    }
end

c2.receive
puts "Done"
1 Like

On second thoughts,

    while i = c1.receive? 
        # Do something with i
    end

is just as concise.

1 Like

Unfortunately Crystal’s concurrency implementation is fairly low level at the moment. The building blocks are there, but higher level APIs have yet to be implemented. A lot of that discussion/proposals are within [RFC] Structured Concurrency · Issue #6468 · crystal-lang/crystal · GitHub.

1 Like

There was a related discussion at [RFC] Implement Ruby's Enumerator Class · Issue #6357 · crystal-lang/crystal · GitHub and [WIP] Implement ruby-style Enumerator by felixbuenemann · Pull Request #6385 · crystal-lang/crystal · GitHub in the past.

1 Like