Section 5 of 26
Conduitese by example
These examples cover current development source reviewed on 9 October 2026.
The standalone language examples can be saved as .conduit source and checked
with conduit check example.conduit. Repository domain examples require their
own reviewed catalog; not every domain Kind is installed in the standard CLI.
Their source links identify that boundary. A source fragment is labeled as
such. Checking, expansion and execution prove different things.
For a deeper worked tutorial, start with units and quantities. The feature example index maps the remaining language surfaces and separates current source from proposed extensions.
Hello: a finite pipeline
Current tree: plots/hello/main.conduit
plot hello {
upper: text/upper
show: face/text("Message")
"Hello, world." >> upper >> show
}.
There is no explicit main function, process, display handle, or stdout. The plot composes semantic work. The full stop says drain completes the plot.
Clock: a standing live plot
Current tree: plots/clock/main.conduit
plot clock-demo {
clock: time/every(1s)
clock >> face/tick("Clock tick")
}
No trailing full stop. The plot remains alive between ticks.
Memory Lantern: input, editing, and Current
Current tree: plots/memory-lantern/main.conduit
The saved layout selector currently runs in the browser; native Hosts use the keyboard-only companion with the same authored default layout.
plot memory_lantern {
keyboard: input/keyboard
keymap: input/keymap
message: text/edit(maximum-bytes = 256)
show: face/text("Message")
keyboard.key >> keymap.key
keymap.text >> message.fragment
message.current >> show.text
}
The editor exposes current text. The plot does not own a window, DOM node, terminal, or framebuffer.
input/keymap defaults to the complete US International layout with AltGr dead
keys. Layouts themselves are typed Conduitese values. For a deliberately small
custom layout, add these immutable values before the gears and pass layout:
base = [{ usage: 4, shift: false, altgr: false, action: text("a") }]
overlay = [{ usage: 4, shift: false, altgr: false, action: text("λ") }]
layout = { layers: [base, overlay], compositions: [] }
keymap: input/keymap(layout = layout)
Physical A now emits λ: later layers override earlier bindings for the same
usage and modifier level. A reusable Plot can accept layout: KeymapLayout and
forward that value. The complete layered Memory Lantern
keeps the ordinary keyboard → keymap → editor → face connections.
See the layout schema, four-level reference, and dead-key behavior.
Pocket Theremin: quantities and retained state
Current tree: plots/pocket-theremin/main.conduit
# The pitch law is ordinary Conduitese. Convert distance to a dimensionless
# number of centimetres, then lower pitch by 55 Hz per centimetre. Clamping is
# explicit; unit conversion and arithmetic never silently round.
plot theremin-pitch (
>> distance: Distance
frequency: Frequency >>
) = (distance <= 0cm ? 1760Hz : distance >= 30cm ? 110Hz : 1760Hz - (distance / 1cm) * 55Hz)
# The one canonical Theremin. Both controls describe portable meaning. Hosts
# own acquisition, cadence, and playback; this Plot owns the instrument law.
plot pocket-theremin (
>> pitch-distance: Distance
>> volume: Scalar
>> cadence: value/tick@1...
audio: audio/pcm-frames@1...| >>
) {
pitch: theremin-pitch
frequency: keep Frequency(440Hz) for this play
tone: audio/continuous-tone
gain: audio/apply-gain
pitch-distance >> pitch.distance
pitch.frequency >> frequency
frequency >> tone.frequency
cadence >> tone.cadence
tone.audio >> gain.source-audio
volume >> gain.amplitude
gain.audio >> audio
}
The pitch law is visible Conduitese: each centimetre lowers pitch by 55 Hz,
clamped to 110–1760 Hz. An expression plot can use its declared input name;
distance denotes the value arriving at that input. The instrument ends with
}, keeping its live completion policy. A trailing }. would declare semantic
completion and is inappropriate for this continuously played instrument.
keep retains the current pitch for this play, starting at 440 Hz. Every
cadence tick samples that pitch and requests the next phase-continuous PCM
block, even when the hand stays still. The tone reads the retained Current frequency
on that cadence; its faults keep their declared abnormal propagation. The
second control changes volume.
The controller binding supplies a 40 ms cadence and selects
audio/continuous-play. Playback remains externally driven until Stop or input
closure, with at most two queued PCM blocks and the Host acoustic gain cap.
The finite audio/play contract retains its lifetime quotas. Stop cancels queued
audio and ends the play and its retained state.
Quantity addition/subtraction, same-family ratios, and Scalar scaling are
checked ordinary expressions. Ratios must fit Scalar's exact millionth carrier;
unrepresentable results refuse instead of silently rounding. Dividing by 1cm
keeps this law exact for the controller's admitted values.
The quantity tutorial also has standalone conversion
examples checkable in the installed CLI.
Button across the room: meaning without transport
Current tree: plots/button-across-room/main.conduit
plot button_across_room {
button: input/button
state: input/button-indicator-state
indicator: face/indicator-state("Button state")
button >> state >> indicator
}
Nothing here says whether button and indicator are on the same host. If planning places them apart, a line may realize the crossing cord.
Desk Telegraph: reusable plots as gears
Current tree: plots/desk-telegraph/main.conduit
plot text-record (
text: Text >> record: TypedRecord
) {
wrap: record/text-to-typed
text >> wrap.text
wrap.record >> record
}
plot bounded-record-send (
maximum-items: Count = 4
maximum-frame-bytes: Count = 4096
frame: FramedTypedRecord >> queued: FramedTypedRecord
) {
queue: record/ordered-send-queue(maximum-items, maximum-frame-bytes)
frame >> queue >> queued
}
These are declarations excerpted from the larger Desk Telegraph source. A plot can itself define reusable semantic work and then be invoked like another kind. The standard CLI currently refuses these record Port profiles as exceeding canonical bounds; this source excerpt is not a standalone execution recipe. Use text identity for a standalone checked reuse example.
Firefly Choir: omission is semantic composition
Current tree: plots/firefly-choir/main.conduit
plot pulse-manifestation (
>> tick: value/tick@1...
) {
observe: time/pulse-observe(period-ms = 240)
light: face/pulse("Pulse activity")
tick >> observe.tick
observe.observation >> light.pulse
}
This is light-only because there is no tone gear and no tone cord. Sound is not a runtime flag that a host may quietly toggle.
Explicit enrichment
plot pulse-light-tone-manifestation (
>> tick: value/tick@1...
) {
observe: time/pulse-observe(period-ms = 240)
light: face/pulse("Pulse activity")
tone: sound/pulse-tone
tick >> observe.tick
observe.observation >> light.pulse
observe.observation >> tone.pulse
}
The fan-out is visible.
Bounded navigation: portable intent down to motion requests
Current tree: plots/bounded-navigation/main.conduit
plot bounded-navigation (
>> pose: NavigationPose
>> goal: NavigationGoal
>> traversability: NavigationTraversability4x4
>> time: NavigationTime
decision: NavigationRouteDecision >>
control: NavigationControl >>
request: RoboticsMotionRequest >>
) {
route: navigation/route-grid4
timing: navigation/time-parameterize
controller: navigation/local-control
pose >> route.pose
goal >> route.goal
traversability >> route.traversability
time >> route.time
route.decision >> decision
route.decision >> select(NavigationRouteDecision.route, unmatched=drop) >> timing.route
time >> timing.time
timing.trajectory >> controller.trajectory
pose >> controller.pose
time >> controller.time
controller.control >> control
controller.control >> select(NavigationControl.motion, unmatched=drop) >> request
}
The plot ends at semantic body-motion intent. Robot authority and actuator lowering belong to the plan and host realization.
body Chat: application meaning, model choice still realization
Current tree: plots/body-chat/main.conduit
plot body-chat (
>> interaction: FaceInteraction...|
face: Face...| >>
) {
ui: chat/state(title = "Body Chat", history-label = "Conversation", input-label = "Message", submit-label = "Send", status-label = "Body", maximum-history-items = 16, maximum-message-bytes = 256)
submit: chat/submit(action = "chat/send", maximum-message-bytes = 256)
available: boolean/literal(value = true)
availability: chat/current-connection
context: body/conversation-context
prompt: body/chat-prompt
model: llm/generate-flow(maximum-input-bytes = 4096, maximum-context-items = 1, maximum-output-bytes = 2560, maximum-work-units = 4096, maximum-history-items = 0)
text: llm/result-flow-to-text
available.value >> availability.source
availability.value >> ui.live
ui.face >> face
interaction >> submit.interaction
submit.message >> prompt.message
context.context >> prompt.context
prompt.human-message >> ui.message
prompt.request >> model.request
model.result >> text.result
text.text >> prompt.response
prompt.body-message >> ui.message
}
The semantic model operation is named. Provider protocol, URL, credentials, or Ollama identity do not belong in the plot.
A mask is an ordinary plot
Current tree: plots/native-graphical-mask/main.conduit
plot native-graphical (
>> face: Face
interaction: FaceInteraction...| >>
show: Show >>
) {
spread: face/tee("Shared Face")
surface: face/show-resource-source("Output resource")
render: face/resource-renderer("Resource view")
human: face/interaction("User actions")
face >> spread.face
spread.face >> render.face
surface.show-resource >> render.show-resource
spread.face >> human.face
render.show >> human.show
render.show >> show
human.interaction >> interaction
}
mask is a role, not a special declaration or second UI language.
Checked refinements
Canonical:
plot guarded (
>> name: Text <= 32B not in ["root", "admin"]
>> count: Count in 1..=100
>> code: Text <= 64B ~ /[A-Z]{2}[0-9]{2}/
) {
}
These relations become part of checked semantic type identity. This declaration demonstrates the checked Fore only; its empty body supplies no consuming behavior. The refinements belong to the Types, rather than to runtime validation callbacks.
Glyphs remain inspectable gears
Canonical:
with text/upper as ^^
input ^^ output
a >< b >< c >> merged
note @ save-request >> snapshot
The checker can always expose text/upper, flow/merge, and current/sample behind the concise spelling.
A native semantic type
Merged current tree:
type LinguisticOffsetBasis =
unicode_scalar
| utf8_byte
The Rust binding is generated from this authored type.
One type family, exact concrete values
The current data types include this generic record and its bounded-text specialization:
type DataGenerationValue<T> = {
namespace: DataGenerationNamespace
value: T
}
type DataGenerationTextValue = DataGenerationValue<Text <= 4096B>
DataGenerationNamespace is defined in that same source. T ranges over
checked semantic types, and the application fixes one exact finite value shape
before play. Generated bindings consume that checked shape. The generic family
does not imply unbounded values or a runtime type-erasure layer.
Separate origin from certainty
These declarations are taken from the human-experience types:
type ExperienceOrigin =
observation
| human_reported
| remembered
| model_derived
| imagined
type ExperienceTemporalRole =
current
| recent
| stale
| historical
type ExperienceCertainty =
certain
| uncertain
Origin, age, and certainty are different facts. An uncertain observation and a certain recollection should not collapse into one flag. These finite variants make the distinctions available to checking and generated bindings; the vocabulary alone does not prove an observation happened or make every consumer report it honestly. That still needs the source's evidence and the consuming contract.
A pack
Canonical:
pack house/sensors (
version = 1.4.0
) {
ship temperature
need math/geometry = ^2.1
}
conduit.lock carries exact resolved truth. Imports grant no runtime authority.
body wardrobe
Canonical:
with masks/native-graphical as graphical
with masks/spoken as spoken
body roseau {
wear graphical, spoken
want graphical over spoken
}
The body permits either mask. The optional want line expresses its preference;
the comma list does not.
host construction
Canonical:
host tiny-screen (
target = conduitos/x86_64/pc
build = release
) {
surface: resource face/surface (
slots = 2
bytes = 2MiB
)
display: base machine/display
graphics: back face/graphics (
surface = surface
display = display
)
bounds = {
heap: 8MiB,
calls: 32,
signs: 256
}
}
This is construction source. A successful parse does not claim the machine booted or the display exists.
Bounded collection behavior
A reusable plot can take exact checked behavior as a parameter. This is the
flow/each wrapper from the
activation tests:
plot flow/each (
item: type
result: type
transform: kind (
>> value: item
mapped: result >>
)
>> values: item...|
mapped: result...| >>
) {
each: activate(maximum-items = 4) transform()
values >> each.value
each.mapped >> mapped
}
transform is checked at specialization time. activate bounds its work and
keeps each selected invocation inspectable. The wrapper's name is defined by
this source; it is not a promise that bare flow/each(...) resolves everywhere.
For selection, folding, scanning, and collection proof, continue with bounded activation in the reference. That reference gives the exact body fragments, required fores, and std/browser proof boundaries. #4378 is completed work, not a remaining syntax gap.
A record owns its law
type Interval = {
start: U32
end: U32
where .start <= .end
}
The law belongs to the type and is enforced when generated bindings construct
or decode a value. See the real
TextSpan declaration.
Completed #4639 carries this
relation into consuming-plot arithmetic proofs: .end - .start can be proven
safe, while .end + 1 remains checked unless an upper bound justifies it.
Only operations established safe by the proof lose their runtime check.
A pure plot with a default parameter
plot increment (
factor: U8 = 2
>> value: U8
result: U8 >>
) = (. * factor)
An expression plot has one current runtime input, .. It can capture an
immutable startup parameter. Calling increment(factor = 3) specializes that
parameter before play; increment(3) is the positional form. Omitting it uses
2. Exact integer overflow remains checked; a default does not license wrapping.
Give an arithmetic invariant to the type
type AlmostU32 = U32 where . < 4_294_967_295
plot next (
>> value: AlmostU32
result: U32 >>
) = (. + 1)
The input law establishes that adding one fits U32. This is a scalar law;
the earlier Interval example is a record law. Both are checked facts.
For explicit widening, the portable expression below returns 65313 for 255:
plot widen (
value: U8 >> result: U64
) = (value/u64(value/u16(.)) * 256 + 33)
See the widening tests.
Construct a nested record
type Inner = {
value: I128
}
type Outer = {
inner: Inner
}
plot nested (
input: I128 >> output: Outer
) = ({ inner: { value: . } })
For input 7, the result is { inner: { value: 7 } }. A consuming expression
can project .inner.value; the named record identity remains checked.
Choose a payload-bearing variant
type Choice =
known I64
| unknown
plot choose (
>> value: I64
result: Choice >>
) = (. >= 0 ? Choice.known(.) : Choice.unknown)
Input 7 yields Choice.known(7); input −1 yields Choice.unknown.
Only the selected pure ternary branch evaluates. Payloadless construction
requires no empty call. A routing companion to append to the same source is:
plot route-choice (
>> value: Choice <= 4096B
known: I64 >>
unknown: Empty >>
) {
value >> ? {
[Choice.known] >> known
[Choice.unknown] >> unknown
}
}
Both alternatives have a route. Matching carries the selected payload directly
to its destination. Current arm syntax uses >>, not a colon.
Finite collections and variable-length sequences
type Samples = collection U16 = 2
plot make-samples (
>> value: U16
result: Samples >>
) = ([1, 2])
Samples has exactly two elements. The input activates this constant-producing
expression; it does not change the two samples.
type Labels = sequence Text <= 2
plot labels (
>> value: Boolean
result: Labels >>
) = (["alpha", "β"])
Labels admits zero, one or two elements. Replacing the result with []
produces a real empty sequence. Three labels or a Boolean element refuse.
The sequence bound counts items; Text <= 2B bounds bytes instead.
Check an index against the actual length
This complete checked-expression example comes from the prepared selection tests:
type Request = {
bytes: sequence U8 <= 4
index: U64
}
type Result =
octet U8
| short
plot guarded-index (
value: Request >> result: Result
) = (.index < sequence/length(.bytes) ? octet(sequence/at(.bytes, .index)) : short(empty))
The selected branch uses a finite checked semantic call. An index inside the
capacity but outside the actual count yields short; capacity is not length.
The unqualified constructors here are resolved from the exact expected Result
Type, as in the test. Qualified constructors are useful when ambiguity exists.
The byte observation tests
apply the same law with Bytes <= 2048B, bytes/length and bytes/at.
Specialize a reusable plot
plot identity (
item: type
>> value: item
result: item >>
) {
value >> result
}
plot text-identity (
>> value: Text
result: Text >>
) {
value >> identity(item = Text) >> result
}
The named argument binds a compile-time Type. When the Fore supplies enough
information the checker can infer it; unresolved parameters never reach play.
This differs from native Pair<T> family application.
A private nested plot
plot outer (
item: type
>> value: item
mapped: item >>
) {
plot helper (
>> inner: item
mapped: item >>
) {
inner >> mapped
}
helper: helper
value >> helper >> mapped
}
The helper captures the exact compile-time Type parameter. It is private to
outer; it cannot capture an outer runtime input or startup value as a hidden
closure. Pass such values through its own Fore explicitly.
One shared pool, explicit consumers
The complete pool webchat source declares a finite pool and passes its identity to ordinary consumers:
plot chat/peer (
recv: ChatMessage...| >> send: ChatMessage...|
) {
}
plot pool-webchat {
pool peers: chat/peer(size = 32)
merge: flow/merge(peers)
room: chat/room(peers)
fan: flow/fan(peers)
merge.message >> room.recv
room.send >> fan.message
}
The excerpt supplies the intended member Fore; its realization is separately
selected. The standard CLI currently refuses this ChatMessage Port profile
as exceeding canonical bounds. The finite pool language feature itself has
checking and expansion fixtures
with their own exact catalogs; this excerpt is not an installed chat recipe. The three consumers refer to the same exact pool. Pool size is finite
admission truth, not an unbounded spawn operation or a data-port value.
More exact surfaces
Continue with the examples for pure expressions, filtering and selectors, optional values, retained state, references and Forms, and close, failure, quiescence, cancellation and temporal joins. Each has a separate checked law; none is hidden inside an ordinary assignment.