Fork me on GitHub
#core-async
<
2020-02-21
>
vikeri15:02:25

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 >! ?

bortexz15:02:31

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

4
leonoel15:02:01

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

vikeri20:02:50

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 >!!?

noisesmith20:02:22

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

noisesmith20:02:28

as any other blocking call would

vikeri22:02:34

:thumbsup: