Sadly, put! on a closed channel has never thrown an exception (regardless of what the docstring says).
I'll list the semantics, but note that the wording gets a bit clumsy due to the way threading works. So if I say "if the channel is closed when the put! occurs", the "occurs" is at the time that the lock happens internally to the channel. So it's possible to call put! and then close the channel before the call to put returns. I assume that this behavior makes sense to most. Semantics are thus: Definition of terms: put succeeded - the channel was not closed, and the put found a pending take put enqueued - the channel was not closed, and no takers were found. -------- With this patch: >!, >!! now returns true if the put succeeded. A falsey value is returned if the put was discarded due to the channel being closed. (put! c val) returns true if the put was enqueued or succeeded. (put! c val callback) callback is called with true if the put succeeded. The callback is called with falsey if the value was discarded due to the channel being closed. The part that trips some people up is that the value returned by the put is both returned and handed to the callback, so there are two ways to get the value. ---------- So to answer your question about closing with pending puts. 1) call put! on an open channel with no takes. 2) put! returns true, since the put was enqueued. But since it was enqueued, the callback has not been dispatched. 3) close! the channel. Still no dispatch as close! does not discard data 4) call take!. The take will succeed instantly (due to the pending put), and the callback will be dispatched with true since the put succeeded. Therefore, the value given the callback is less about the status of the channel, and more about if the value has been given to a taker. One more example: 1) call put! on a closed channel 2) put returns falsey 3) the callback is dispatched with falsey Hopefully this helps. Timothy On Thu, Jan 23, 2014 at 2:28 PM, Sean Corfield <s...@corfield.org> wrote: > Can you confirm: > > * Today, calling put! on a closed channel throws an exception (according > to its docstring). > * After this change, calling put! on a closed channel will return nil > instead. > > The current docstring says that the function will be called "when > complete" which I took to mean when the value is actually placed in the > channel (i.e., no longer pending) so I'm confused by your comment about > pending puts... What happens if a put is enqueued on an open channel and > then it is closed before the put is "complete"? It seems like put! would > return true and the function would simply not be called? > > Just trying to make sure I understand this properly. > > I think it's a good change (even tho' it breaks any code that uses put! > and expects it to throw an exception). > > Sean > > On Jan 23, 2014, at 6:05 AM, Timothy Baldridge <tbaldri...@gmail.com> > wrote: > > I'm looking for some feedback on recent changes Rich and I have made to > core.async: > > > > I merged the "put ret" branch into master of core.async. This commit > introduces some changes to the core.async API that provides feedback during > a put! operation. > > > > The changes to the public api are fairly simple: > > > > (let [result (put! c 42 (fn [result] nil))] > > nil) > > > > In this snippet, both result variables (in the callback and in the > return value) will return true, unless the channel is already closed. Since > this value is propagated to >! as well, termination of writers is now > fairly easy: > > > > (loop [x 0] > > (when (>! c x) > > (recur (inc x)))) > > > > Note: these new semantics don't change how pending puts are handled when > a channel closes. So if a put! returns true, the callback will not later be > called with false if the channel is closed. Once a put operation is > enqueued it will stay enqueued until a taker removes the operation. Close! > will still not remove pending puts. > > > > WARNING!!! The inclusion of these changes means we have to break the > public API. The function handed to put! now takes one argument instead of > zero arguments. This will instantly break any code that uses put!. > Therefore when upgrading to 0.1.0-SNAPSHOT you will need to update all > calls to put!. I'm sorry about this, but there's really no other way to get > these changes into the api. > > > > Please let me know about any bugs you find in the current 0.1.0-SNAPSHOT. > > -- "One of the main causes of the fall of the Roman Empire was that-lacking zero-they had no way to indicate successful termination of their C programs." (Robert Firth) -- -- 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. For more options, visit https://groups.google.com/groups/opt_out.