Fork me on GitHub
Jakub Holý (HolyJak)13:07:57

Hi, is there anything like run! or doseq for channels? I would like to do this:

    (run! json/pprint chan) ;; run! doesn’t work here 
    (println "print-receiver: DONE, no more input”))
(I.e. process each item and do something when the channel closes.) So far I have the following but it is long and ugly:
        (if-let [post (<!! chan)]
            (json/pprint post)
          (println "print-receiver: DONE, no more input")))
Thank you for any tips!


why don't you stick this in a go-loop?


(go-loop []
    (when-let [post (<! chan)]
       (json/pprint post)
 (println "done")


I'm aware that this is not what you asked for

Jakub Holý (HolyJak)13:07:33

@slipset: Takk! I am not really sure when to use threads and when go-loops (outside of JS which makes the choice for you). into doesn’t help, I want to print the data as it arrives. Thx for trying! simple_smile


It seems like you generally want to use go, since it works on a shared thread-pool


thread starts up its own thread IIRC


holyjak: just don’t use go blocks to do something that will block the thread (e.g., blocking I/O)

Jakub Holý (HolyJak)13:07:05

(which is exactly what I am doing here) Thanks for the tip!


that's confusing tho... the core.asyn blog says "go is a macro that takes its body and examines it for any channel operations. It will turn the body into a state machine. Upon reaching any blocking operation, the state machine will be 'parked' and the actual thread of control will be released."


what "blocking operations" is it referring to then?


@reubano: blocking in that case refers to channel operations i believe


"blocking" as in "waiting for a channel to get a new value" VS "blocking" as in "calling a synchronous API that potentially blocks an entire thread". Two different blockings


FWIW, Scala actually has a macro that hints the async executer that a call is "long blocking with I/O"


reubano: that text is pretty confusing. They shouldn’t have said “blocking”, they should have said “parking”. But the problem is I think they hadn’t yet introduced the term “park” yet, so they couldn’t really say that.


To understand core.async you need to understand the difference between blocked and parked. blocked means that the actual JVM thread is blocked, the kind of blocked that a thread experiences when it waits on another thread or a synchronized block or is slept. parked is specific to core.async’s go-blocks, and means “the work that this go block was doing will be paused, but the actual underlying JVM thread that was doing this work is not blocked, and is returned to the pool of JVM threads used by all go blocks so that it can service some other go block that has become unparked."


So from your point of view as a programmer, when your go block is parked, it appears that the code inside the go block is “blocked” (scare quotes), as in, it doesn’t continue executing until some future condition (and that condition is that the go block is unparked). But the real JVM thread isn’t blocked at all, it’s just not continuing to execute the code in the go block, for now.


And, btw, the way to park a go block is to use <! on a channel that has no values to deliver, or >! on a channel that cannot currently accept a value. Those are the parking operations. The >!! and <!! operations actually block the current JVM thread, and so that thread is not returned to the pool and made available to other go blocks. Those are the blocking operations.


(Though obviously there are other ways to block a JVM thread, as described previously… Thread/sleep being an obvious one.)


I have the feeling that core.async has been one of the most powerful addition to Clojure but it suffers the "Missing Manual" syndrome. We can find plenty of beginners tutorials but it is harder to find more involved examples. Someone should write a book ! Any volunteers 😉


These videos are excellent, and Tim Baldridge is one of the authors of core.async:


Thanks everyone for the clarifications. Makes sense now.


Agreed the blog posted should be reworded though to avoid future confusion.