Channel Directions in Clojure
In Clojure, we can specify the direction of a channel when it’s used as a function parameter. This increases the type safety of the program.
(ns channel-directions
(:require [clojure.core.async :as async :refer [>! <! >!! <!! go chan buffer close!]]))
;; This `ping` function only accepts a channel for sending
;; values. It would be a compile-time error to try to
;; receive on this channel.
(defn ping [pings msg]
(>!! pings msg))
;; The `pong` function accepts one channel for receives
;; (`pings`) and a second for sends (`pongs`).
(defn pong [pings pongs]
(let [msg (<!! pings)]
(>!! pongs msg)))
(defn -main []
(let [pings (chan 1)
pongs (chan 1)]
(ping pings "passed message")
(pong pings pongs)
(println (<!! pongs))))
To run the program:
$ lein run
passed message
In this Clojure version, we’re using the core.async
library to work with channels. The >!!
and <!!
functions are used for putting values onto channels and taking values from channels, respectively, in a blocking manner.
The ping
function takes a channel and a message, and puts the message onto the channel. The pong
function takes two channels, receives a message from the first channel, and puts it onto the second channel.
In the -main
function, we create two channels with a buffer size of 1, send a message through them using our ping
and pong
functions, and then print the result.
Note that Clojure’s core.async
doesn’t have built-in support for specifying channel direction in function signatures. However, the intent can be conveyed through function documentation and careful usage.