core-async

vikeri 2020-02-21T15:41:25.387500Z

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

bertofer 2020-02-21T15:47:31.389800Z

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

➕ 1
2020-02-21T15:52:01.390400Z

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

alexmiller 2020-02-21T15:54:12.391100Z

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

alexmiller 2020-02-21T15:55:25.392300Z

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

vikeri 2020-02-21T20:00:50.397600Z

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

2020-02-21T20:03:22.398800Z

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

2020-02-21T20:03:28.399Z

as any other blocking call would

alexmiller 2020-02-21T20:30:03.399300Z

can block (not will)

vikeri 2020-02-21T22:01:34.399500Z

:thumbsup: