tur/stm-sync
TMVar and TChan, built on tvar + check.
Since: 2026-08-20
tmvar-new
(tmvar-new [v])
create a TMVar holding a value (full).
| v | the initial value; must not be 0 (see "The empty marker" above) |
A TVar handle serving as a full TMVar.
(let [mv (tmvar-new 42)] ...)
Since: 2026-08-20
tmvar-new-empty
(tmvar-new-empty)
create an empty TMVar.
A TVar handle serving as an empty TMVar.
(let [mv (tmvar-new-empty)] ...)
Since: 2026-08-20
tmvar-take-stm
(tmvar-take-stm [mv])
transaction BODY: block until full, then empty and return.
(atomically (stm (tmvar-take-stm mv)))
Since: 2026-08-20
tmvar-take
(tmvar-take [mv])
block until the TMVar is full, then empty it and return it.
| mv | the TMVar |
The value that was in the slot, as a ptr.
(let [mv (tmvar-new 42)]
(println (:: (tmvar-take mv) :int))) ; => 42
Since: 2026-08-20
tmvar-put-stm
(tmvar-put-stm [mv v])
transaction BODY: block until empty, then fill.
(atomically (stm (tmvar-put-stm mv 7)))
Since: 2026-08-20
tmvar-put
(tmvar-put [mv v])
block until the TMVar is empty, then fill it.
| mv | the TMVar | |
| v | the value to store; must not be 0 |
(let [mv (tmvar-new-empty)]
(tmvar-put mv 7)
(println (:: (tmvar-take mv) :int))) ; => 7
Since: 2026-08-20
tmvar-read-stm
(tmvar-read-stm [mv])
transaction BODY: block until full, return WITHOUT emptying.
(atomically (stm (tmvar-read-stm mv)))
Since: 2026-08-20
tmvar-read
(tmvar-read [mv])
block until full, return the value without emptying.
| mv | the TMVar |
The value in the slot, as a ptr. The slot stays full.
(let [mv (tmvar-new 42)]
(println (:: (tmvar-read mv) :int)) ; => 42
(println (:: (tmvar-take mv) :int))) ; => 42 -- still there
Since: 2026-08-20
tmvar-full?
(tmvar-full? [mv])
is the TMVar currently full? Does not block.
| mv | the TMVar |
true when the slot holds a value.
(println (tmvar-full? (tmvar-new-empty))) ; => false
Since: 2026-08-20
tchan-cons-append
(tchan-cons-append [lst : int v : int] :)
internal: append `v` to the end of cons list `lst`.
tchan-cons-head
(tchan-cons-head [lst : int] :)
internal: first element, or -1 for an empty list.
tchan-cons-tail
(tchan-cons-tail [lst : int] :)
internal: the list without its first element.
tchan-cons-len
(tchan-cons-len [lst : int] :)
internal: number of elements.
tchan-new
(tchan-new)
create an empty TChan.
A TVar handle serving as an empty channel.
(let [ch (tchan-new)] ...)
Since: 2026-08-20
tchan-write-stm
(tchan-write-stm [ch v])
transaction BODY: append a value. Never blocks.
(atomically (stm (tchan-write-stm ch 1)))
Since: 2026-08-20
tchan-write
(tchan-write [ch v])
append a value to the channel. Never blocks (unbounded).
| ch | the TChan | |
| v | the value to append |
(let [ch (tchan-new)] (tchan-write ch 1))
Since: 2026-08-20
tchan-read-stm
(tchan-read-stm [ch])
transaction BODY: block until non-empty, then pop.
(atomically (stm (tchan-read-stm ch)))
Since: 2026-08-20
tchan-read
(tchan-read [ch])
block until the channel is non-empty, then pop the oldest.
| ch | the TChan |
The oldest value in the channel.
(let [ch (tchan-new)]
(tchan-write ch 1)
(tchan-write ch 2)
(println (tchan-read ch))) ; => 1
Since: 2026-08-20
tchan-len
(tchan-len [ch])
how many values are queued. Does not block.
| ch | the TChan |
The number of queued values.
(println (tchan-len (tchan-new))) ; => 0
Since: 2026-08-20
tchan-empty?
(tchan-empty? [ch])
is the channel empty? Does not block.
| ch | the TChan |
true when nothing is queued.
(println (tchan-empty? (tchan-new))) ; => true
Since: 2026-08-20