working with promesa.exec.csp ... there's a slight semantic difference in noticed from manifold and core.async in that:
(sp/put ch :foo)
(sp/close! ch)
@(sp/take ch) ;=> nil
results in nil (i.e. the channel closes before the put happens), whereas with similar manifold and core.async sequences the result would be :foo - presumably because they are both doing some synchronous queueing of puts, whereas promesa.exec.csp is parking until there is a consumer and that never happens
i'm not sure this is a bad thing though ... it's easy enough to compensate for, and puting without waiting on the result is perhaps a code smell anywayanyway, i did a promesa.exec.csp based implementation for my manifold-a-like lib, and it mostly works (still got a few test errors to work through): https://github.com/yapsterapp/promisespromises/blob/e1380827b36652a2b8ad6b03b065288f19f573ec/src/prpr3/stream/promesa_csp.cljc
yep, it is expected behavior difference, and it depends on the channel type. core.async preserves all pending puts to the channel when you call close!, this is why, after a close you can take! it.
promesa on the other hand, clears all queues on close, and resolves with nil all pending operations.
if channel was buffered, the result will be different, the value will be put in buffer synchronously and the take will success with expected value after close!