Range Over Channels in Chapel

In a previous example, we saw how for and range provide iteration over basic data structures. We can also use similar syntax to iterate over values received from a channel.

use IO;

proc main() {
    // We'll iterate over 2 values in the `queue` channel.
    var queue = new channel(string, 2);
    queue.write("one");
    queue.write("two");
    queue.close();

    // This loop iterates over each element as it's
    // received from `queue`. Because we closed the
    // channel above, the iteration terminates after
    // receiving the 2 elements.
    for elem in queue.readAll() {
        writeln(elem);
    }
}

To run the program:

$ chpl range-over-channels.chpl
$ ./range-over-channels
one
two

This example also showed that it’s possible to close a non-empty channel but still have the remaining values be received.

In Chapel, we use a channel to represent a communication channel between tasks. The write method is used to send values to the channel, and readAll() returns an iterator that we can use in a for loop to receive values from the channel.

The close() method is used to close the channel, indicating that no more values will be sent. After closing, we can still read any remaining values from the channel.

Note that Chapel’s channels are somewhat different from Go’s channels. In Chapel, channels are more explicitly created and managed, and the syntax for sending and receiving is slightly different. However, the core concept of using channels for communication between concurrent tasks remains the same.