Just a side note, I thought it would be nice if instead of “you get the value on take” core async had a different semantics — “you get a value or exception is thrown”. I think it matches the JVM platform semantics better. It composes better in go blocks, i.e.:
(defn start-process! []
(a/thread
...start-a-process-that-might-throw))
(a/go
(try
(<! (start-process!))
(catch Exception e
..do-something-else)))
I know you can fake it with <? macro and catching and returning throwables, but this is really a workaround for core-async channel semantics not mirroring JVM execution semantics in the area of error handling.