Fork me on GitHub

A question regarding >! vs >!! Which one should I use here:

(defn f2 [ch]
  (? ch 1)) ; <--

(defn f1 []
  (let [ch (async/chan)]
    (go (f2 ch)))
It’s not “visible” by the go block and therefore I’m unsure if I still should use >! ?


As it’s not visible, you will be unable to use >!, and using >!! will block the go-blocks thread-pool. Usually I’d try to >! from the visibility of the go block, relying on the fn to be pure and tell me what to >!. Another solution can be to (go (>! …)) inside the fn too. In this case the fn can return and the object might still not be on the channel, but sometimes this is fine


another possibility could be to turn f2 into a macro, then you could use >!

Alex Miller (Clojure team)15:02:12

generally it's best if possible to use the parking ops and keep them in the lexical scope of the go

Alex Miller (Clojure team)15:02:25

using the blocking ops is generally bad (b/c they can block and prevent your go blocks from making progress) and there is a system property that will check for this and assert it


My code was simplified so it’s not very easy to incorporate it into a single function. But it seem that the best way of doing it then is to create another go block in f2? I’m not sure I fully understand the blocking of putting things into the channel. I understand that if I block when taking I will block until something is put in the channel from the other end, but if I have a channel (with enough buffered space) then how does it block when I use >!!?


go is a macro that replaces >! and <! and take! and alts! with context switches via code rewriting, >!! is just a blocking call, that locks up the go block


as any other blocking call would