The core.async library provides many high-level features for async programming, but does not protect against classical concurrency problems. Discourje extends core.async and offers high-level abstractions to define message exchange patterns that are run-time validated and enforced between threads.