Concept guide
Kinds, enums, and unions
Kinds give a value named fields. Enums choose one name from a fixed set. Tagged unions choose one shape, with the data that shape needs. Callable types let a verb itself become a checked value.
One program, four kinds of shape
This delivery router uses all four ideas together. Read it once for the outline: a delivery has fields, its priority is an enum, its destination is a tagged union, and publish accepts a formatting verb as data.
a priority is one of routine, urgent
kind delivery:
title: text
priority: priority
attempts: whole
a destination is one of:
a localqueue, with a lane
a webhook, with an endpoint and a retrylimit
a presenter is a way to present, given a delivery called item, returns text
to compact(item: delivery), returns text:
answer "{item.priority}: {item.title} ({item.attempts} attempts)"
to publish(item: delivery, render: presenter):
say render(item)
to route(place: destination), returns text:
when place is a localqueue:
answer "queue {place.lane}"
when place is a webhook:
answer "webhook {place.endpoint}, retry {place.retrylimit}"
to begin:
the shipment is a delivery:
title is "release build"
priority is urgent
attempts is 2
publish(shipment, compact)
the fallback is a localqueue
fallback.lane is "overnight"
say route(fallback)
the primary is a webhook
primary.endpoint is "/deploy"
primary.retrylimit is 3
say route(primary)a priority is one of routine, urgent
kind delivery:
title: text
priority: priority
attempts: whole
a destination is one of:
a localqueue, with a lane
a webhook, with an endpoint and a retrylimit
a presenter is a way to present, given a delivery called item, returns text
to compact(item: delivery), returns text:
answer "{item.priority}: {item.title} ({item.attempts} attempts)"
to publish(item: delivery, render: presenter):
say render(item)
to route(place: destination), returns text:
when place is a localqueue:
answer "queue {place.lane}"
when place is a webhook:
answer "webhook {place.endpoint}, retry {place.retrylimit}"
to begin:
the shipment is a delivery:
title is "release build"
priority is urgent
attempts is 2
publish(shipment, compact)
the fallback is a localqueue
fallback.lane is "overnight"
say route(fallback)
the primary is a webhook
primary.endpoint is "/deploy"
primary.retrylimit is 3
say route(primary)Kinds describe what belongs together
kind delivery: declares one described thing with three fields. Each field has a name and a type. The declaration creates the shape; the indented block under the shipment is a delivery:creates a value and fills its fields by name.
Read a field with the dot form, such as item.title, or with the prose form, such as the title of the item. The formatter uses dots because several reads sit inside one piece of text. Both forms refer to the same declared field.
Enums name a closed set of choices
a priority is one of routine, urgent declares two values of the same enum type. A delivery cannot hold an arbitrary word in its priority field. It holds one of those members, and the member renders by name when placed in text. That is why the first output line begins with urgent.
Enum comparisons use ordinary when conditions. The compiler does not apply tagged-union exhaustiveness checking to an enum comparison chain. Use an else: when the remaining members share one behavior, or name the members you mean to handle.
Tagged unions carry the data for one case
A colon after is one of: opens a tagged union. Here, a destination is either a localqueue with a lane, or a webhook with an endpoint and a retry limit. Each value carries one active tag and only that variant's payload.
The program constructs each variant by name, then fills its payload fields. Current Vision infers those payload types from their writes, solane and endpoint become text whileretrylimit becomes a whole number.
A parameter typed as destination could hold either variant.route narrows it with when place is a localqueue: before readingplace.lane. Reading a payload before that check is a compile error: the compiler cannot prove the field is present. A chain of union tag checks must cover every declared variant, or end in else:.
Callable types put a shape around a verb
presenter is the type of a verb that takes one delivery and returns text. The parameter names in the callable declaration explain the positions; their declared types are what the compiler checks.
publish(shipment, compact) passes compact as a value. Inside publish, render(item) calls whichever matching verb arrived. The bound verb must match the callable's parameter types, return type, world-touch marker, mutation shape, and failure set. This tutorial uses the plain, infallible case; the precise fallible and mutating forms belong in the language reference.
Add one destination and one presentation
Add a deadletter, with a reason todestination. The compiler will point out thatroute no longer covers every variant. Add the matching branch, construct a dead-letter destination in begin, and make its line read dead letter: expired.
Then write a second presenter that returns onlyitem.title, and pass it to publish. The call site changes; publish does not. If you want to revisit the construction block first, see Reading a Vision program. The later reference will cover field inference, shared enum names, and every callable shape in detail.