The (go (<! c)) will add a pending take! on the c channel. The go block 
will not proceed while waiting for the take to proceed. The (>!! c 42) will 
use that pending take and immediately fulfill it without checking the 
buffer (there is none).

I really can't explain this very well so I'd recommend watching some of the 
talks on core.async instead. All the topics are covered

- https://vimeo.com/100518968
- https://www.youtube.com/watch?v=enwIIGzhahw
- https://www.youtube.com/watch?v=096pIlA3GDo

On Monday, May 20, 2019 at 3:18:17 PM UTC+2, Brian Beckman wrote:
>
> 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/568ddcbe-2e3a-4e6b-a97e-c060e3b7fb37%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to