The follwing function implements mapping functionality using channels, similar to the behavoiur of the normal clojure map
I got this code example from the book Seven concurrency models in seven weeks by Paul Butcher. It seems that this code is already outdated because when executing it, it throws the follwing error message. Does anyone know how to fix the function?
Error Message:
Can only recur from tail position {:exprs nil, :form (recur)
Code:
(defn map-chan [f from]
(let [to (chan)]
(go-loop []
(when-let [x (<! from)]
(>! to (f x))
(recur))
(close! to))
to))
My first fixing attempt: // same error as origin
(defn map-chan [f from]
(go-loop []
(do
(let [to (chan)]
(when-let [x (<! from)]
(>! to (f x))
(recur))))
(close! to)
)
)
Indeed, it does not work; this is also mentioned in the errata to the book.
You can place the
close!
function call outside the loop to ensure thatrecur
is in final position (note that you have to usego
andloop
instead ofgo-loop
for that):