Channel Directions in Crystal

Channel directions in Crystal can be specified using the Channel(T).send and Channel(T).receive types. This specificity increases the type-safety of the program.

# This `ping` function only accepts a channel for sending
# values. It would be a compile-time error to try to
# receive on this channel.
def ping(pings : Channel(String).send, msg : String)
  pings.send msg
end

# The `pong` function accepts one channel for receives
# (`pings`) and a second for sends (`pongs`).
def pong(pings : Channel(String).receive, pongs : Channel(String).send)
  msg = pings.receive
  pongs.send msg
end

def main
  pings = Channel(String).new(1)
  pongs = Channel(String).new(1)
  spawn { ping(pings, "passed message") }
  spawn { pong(pings, pongs) }
  puts pongs.receive
end

main

To run the program:

$ crystal channel_directions.cr
passed message

In Crystal, channels are used for communication between fibers (lightweight threads). The Channel(T).send and Channel(T).receive types are used to specify the direction of the channel.

The ping function takes a send-only channel (Channel(String).send) and a message. It sends the message on the channel.

The pong function takes a receive-only channel (Channel(String).receive) and a send-only channel (Channel(String).send). It receives a message from the first channel and sends it on the second channel.

In the main function, we create two buffered channels with a capacity of 1. We then spawn two fibers: one for ping and one for pong. Finally, we print the message received from the pongs channel.

Crystal’s channel system is similar to the one in the original example, allowing for safe concurrent communication between fibers.