No matching definitions.

schan

stdlib/schan.tur

session-typed channel wrappers over a linear opaque handle.

SChan<p> is a thin generic wrapper over a synchronous blocking channel that carries a protocol phantom p. Each operation advances the phantom:

schan-send  : SChan<SSend T R> -> T  -> SChan<R>
schan-recv  : SChan<SRecv T R>       -> (Pair T SChan<R>)
schan-close : SChan<SClose>          -> nil

The phantom is threaded through the result type, so a caller cannot skip a step or reorder send/recv: doing so is a compile-time type error (TUR-E0001 phantom mismatch). Combined with the :linear discipline (under -Xlinear), every protocol step happens exactly once and in order.

(The plan's ideal schan-recv : SChan<SRecv T R> -> Pair<T SChan<R>> is blocked by a monomorphizer limitation around parametric aggregates whose element type is a phantom carried inside an opaque -- see schan-recv's docstring and docs/archive/history/generic-struct-opaque-element-miscompile.md. recv therefore returns the typed continuation directly and delivers the received value through a caller-provided cell, which keeps the continuation protocol fully checked.)

The wrapper operations carry their channel work directly as inline-C over the opaque carrier (the phantom is erased at the C ABI), so the typed surface adds no runtime overhead beyond the underlying channel. The low-level tur/chan keeps its untyped surface for callers that do not want the protocol discipline.

Since: S1

defopaque

SSend

(defopaque SSend [T R] :int)

protocol step: send a value of type T, then continue as R.

defopaque

SRecv

(defopaque SRecv [T R] :int)

protocol step: receive a value of type T, then continue as R.

defopaque

SClose

(defopaque SClose :int)

protocol terminus: the channel is closed.

defopaque linear

SChan

(defopaque SChan [P] :ptr<void> :linear)

a linear channel handle carrying a protocol phantom P.

Lowers to the underlying :ptr<void> channel in the C ABI; the phantom P is erased at runtime. :linear so the protocol cannot be replayed: each operation consumes the handle and yields the continuation at the next step.

Since: S1

defn

schan-new

(schan-new [P])

open a session-typed channel running protocol P.

capring-buffer capacity (>= 1)

A fresh SChan<P>. The protocol P is fixed by the call site's expected type (or an ascription).

(:: (schan-new 4) (SChan (SSend int SClose)))  ; => SChan<SSend int SClose>

Since: S1

defn

schan-send

(schan-send [T R])

send a T over a channel whose protocol begins with SSend T R.

cchannel at protocol SSend<T R> (consumed)
vthe value to send

The same channel, advanced to protocol R.

(let [c2 (schan-send c 42)] ...)  ; c : SChan<SSend int R> => c2 : SChan<R>

Since: S1

defn

schan-recv

(schan-recv [T R])
defn

schan-close

(schan-close [c :(SChan SClose)] :nil)

close a channel whose protocol has reached SClose.

cchannel at protocol SClose (consumed)

nil. The underlying channel is freed.

(schan-close c)   ; c : SChan<SClose>

Since: S1

Internal definitions
schan-recv-value-- receive a T from a channel whose protocol begins with SRecv T R.
schan-advance-recv-- internal: retag the channel from SRecv T R to R.