Without going into the details of channels, we can define a notion of directionality for channels. Suppose we have some channel type chan(bool).
chan(bool) X; chan?(bool) Y; chan!(bool) Z;
This declares a channel X with unspecified direction (nondirectional), Y as a read-only (receive-only) directional channel, and Z as a send-only directional channel. Send-only and receive-only channels are the most useful in process port declarations — what use are uni-directional channels in the global or local scopes1?
[1] Should multi-module linkage ever be specified and implemented, a receive-only channel in one module could connect to a send-only channel in another module.