Clojure future and promise — Simple Async with @deref and deliver | Episode 28

0views
C
CelesteAI
Description
Two small primitives that cover the most common async patterns. `future` takes a body and runs it on a background thread — you get a reference back, and `@` deref returns the body's value when it's ready. `promise` is an empty cell that any thread can `deliver` a value into — `@` blocks until someone does. Both are one-shot: once set, the value is fixed. In this episode we run three `(future (slow-double n))` calls in parallel and collect their results in input order, then demo a classic producer/consumer handoff where the main thread blocks on `@p` until a background future delivers. Student code: https://github.com/GoCelesteAI/clojure-for-beginners/tree/main/episode28 Every keystroke is shown on screen with generous pauses so you can follow along at your own pace. What You'll Learn: - `(future body)` — run `body` on a background thread; returns a future reference - `@future` / `(deref future)` — block until done, return the value (cached after) - `(realized? f)` — non-blocking check for done - `(promise)` — create an empty cell - `(deliver p v)` — fill a promise once; subsequent delivers are no-ops - `@promise` — block until delivered - Parallel fan-out: run N futures, `(map deref fs)` preserves input order - When to reach for each: `future` when *you* supply the work; `promise` when *someone else* supplies the value Timestamps: 0:00 - Intro 0:15 - Preview: one-shot async values 0:51 - The code — slow-double helper + main 1:12 - Start the REPL, load the namespace 1:34 - (future ...) returns immediately 1:41 - The future object — status + val 1:48 - @f — already 42 1:56 - (realized? f) — true 2:03 - Three futures in parallel 2:21 - (map deref fs) — (6 2 10), input order 2:29 - (promise) + (realized? p) — false 2:43 - A future delivers from a background thread 2:51 - @p blocks then returns the delivered value 3:09 - Control-D 3:25 - clj -M:run — full demo 3:34 - Recap 4:12 - What's next: Episode 29 Key Takeaways: 1. `future` is for work you're launching now — you know what the computation is, just want it off the main thread. 2. `promise` is for work where the computation isn't the focus — you need a handoff point between threads. 3. Both use `@` to deref. Both block the caller until the value is ready. Both are one-shot. 4. `future` caches the result after the body completes — the first `@f` blocks, subsequent `@f` calls are instant. 5. Parallel `(map deref fs)` preserves input order, not finish order. That's almost always what you want. 6. `realized?` is your non-blocking peek — useful for polling or conditional waits. Phase 5 continues. Next up: `core.async` — channels and go blocks for structured async coordination. Taught by CelesteAI. Like and subscribe for more Clojure tutorials!
Back to tutorials

Duration

Added to Codegiz

April 20, 2026

📖 Read the articleOpen in YouTube