Thanks, Thomas. I shouldn't have included the quoted code about (<!! c) in my question because it distracts from what I really want to know, and what I want to know is all about how (go (<! c)) "makes buffer space available" so that (>!! c 42) doesn't block.
The following is an attempt to clarify my question. I first (go (<! c)) and give the name d to the result, which is a channel that I am going read-from later. Channel d is "connected to" or "relayed from" c. I then (>!! c 42), and then (<!! d), both on the blocking "UI" thread. Everything works. I wasted your attention by writing some code that would block (<!! c) if it weren't quoted. Here is the part I don't understand: the documentation says that (>!! c 42) will block "if there is no buffer space available," and the documentation does not specify any other conditions. Well, I created c with no buffer space, so, (>!! c 42) must block unless something else "makes buffer space available," assuming the documentation is correct. The only other interaction with c that could possibly be alive at the time when I do (>!! c 42), is (go (<! c)), so (go (<! c)) must "make buffer space available," assuming the documentation is correct. My understanding of (<! c) (and I am suspicious of my understanding), is that (<! c) makes a rendezvous available, not a buffer. If that understanding is correct, then (>!! c 42) should block because there is no buffer available. On Sunday, May 19, 2019 at 1:48:16 PM UTC-7, Thomas Heller wrote: > > (<!! c) will hang because the value you put into c has already been taken > by the first go (running in a different thread). So it is blocking until > something puts another value into c. Since nothing ever does your program > hangs. > > If it helps you can read "go" as "please run this somewhere else, possibly > at a different time" and let the current thread continue after the go. > > I can't explain this very well but the documentation aspect is accurate. > > On Sunday, May 19, 2019 at 7:33:07 PM UTC+2, Brian Beckman wrote: >> >> The documentation for >!! reads: >> >> ------------------------- >> clojure.core.async/>!! >> ([port val]) >> puts a val into port. nil values are not allowed. Will block if no >> buffer space is available. Returns true unless port is already closed. >> >> >> I have a case where I believe that the channel has no buffer, I park a >> "pseudothread" in a go block reading off that channel via <!, and then >> (lexically, not temporally), put to the unbuffered channel via >!!: >> >> (let [c (chan) ;; NO BUFFER! >> d (go (<! c)) ;; park a pseudothread to read c >> e (>!! c 42)] ;; blocking write to c, will unpark c's pseudothread >> (println {:c-coughs-up '(this will hang (<!! c)), >> :d-coughs-up (<!! d), >> :what's-e e}) >> (close! c) (close! d)) >> >> {:c-coughs-up (this will hang (<!! c)), :d-coughs-up 42, :what's-e true} >> >> >> This case leads me to wonder whether the documentation might read >> >> >!! will block if there is no buffer space available *and* if there is >> no *rendezvous *available, that is, no pseudothread parked waiting for <! >> . >> >> but it's more likely that I completely misunderstand core.async because I >> just made up the notion of a pseudothread in my struggle to understand! >> >> >> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/fe9fc48c-d651-434d-8743-0045438291f1%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.