Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 5 Nov 2026. What's built · Install 0.3.0
jadpo
ReferenceValues and types

LanguageValues and types

Named types

On this page

Most of a program's types are named types: a built-in representation, a name that says what the value means, and the rules a valid value must follow.

example
type Stock = Int {    min: 0}type Quantity = Int {    min: 1    max: 1000}type ProductName = Text {    min_length: 1    max_length: 120}type OrderId = Uuid {}

OrderId has no rules, but it is still its own type: an OrderId can't be passed where another UUID-based type is expected. Every type declaration creates a new type. There are no aliases, names that are just another way of writing an existing type.

A named type can build on another named type and add rules. The new type keeps every rule of the one it builds on, so it can be used wherever that type is expected. The other way round needs a construction, which checks the extra rules.

example
type ProductName = Text {    min_length: 1    max_length: 120}type ShortProductName = ProductName {    max_length: 40}function catalogue_name(name: ShortProductName) -> ProductName {    return name}

Constraints

Constraint For Value Meaning
min, max Int, Decimal number Inclusive bounds
min_length, max_length Text, Bytes, List<T>, Set<T>, Map<K, V> whole number Inclusive bounds; text counts Unicode characters, collections count items
pattern Text string A regular expression the text must match
format Text email The text must be an email address
dimensions a type built on Vector whole number, 1 to 16,000 Exactly that many items (AI types)
distance a type built on Vector a VectorDistance: cosine (the default), euclidean or inner_product How its vectors are compared: ai.distance and its index follow it (Storing a vector)

Each constraint is written name: value, one per line. There are no other constraints and no custom validation functions.

A refinement, a type that builds on another, can only add to the rules it inherits. These are errors:

  • type.constraint_contradiction: a max below an inherited min, or the other way round, and the same for lengths and durations. It is also a Decimal refinement whose scale differs from the one it inherits, since the scale decides how the value is stored and sent; a currency other than the one it inherits, in a Money type's currency: or a rate type's from: and to:; and a vector type's dimensions: other than the one it inherits or outside its lengths.
  • type.constraint_loosened: a bound looser than the one it inherits, such as max_length: 50 on a type with max_length: 40.

The same rules hold for the settings on the fields of every type with fields, entities and events included. The settings that only an entity's or an event's fields take (generated, on_delete, unique, immutable, role, personal, erase, retention) are described with those features, starting at Entities, stores and migrations.

An exact number holds at most 38 digits, and a number literal with more is type.invalid_literal.

Units and money in plain numbers

A type named for a unit but built on a plain number, such as type Grams = Int {}, holds a weight that nothing knows is a weight: a value in kilograms passes for one in grams, and it adds to a price. The standard types keep the unit with the number: Mass, Length and the other physical quantities, Duration, Money and Percentage. So a type built on Int or Decimal, directly or through another type, whose whole name is one of their units is type.unit_as_number, which names the standard type:

The whole name is It holds
A quantity's unit, by its name or a code of two letters or more: Grams, Metres, NauticalMiles, Kg, Kwh That quantity: Mass, Length, Energy
Ms, Millis, Milliseconds, Seconds, Secs, Minutes, Mins or Hours Duration
A currency's minor unit: Pence, Penny or Cents Money
Percent or Pct Percentage

A plural matches as its singular. The words are the data jadpo suggest's name signal reads (Signals), so the two never disagree. A unit that is also a currency's name, Pounds, names both types: Mass for a weight, Money for an amount of money. A currency's other major units (Dollars, Euros) are no unit, so they are left alone. A name with more in it, such as PricePence or WeightGrams, is left to jadpo suggest, which reports it as a name finding. Build the type on the standard type instead, named for what it holds:

example
/// What a parcel weighs, up to the courier's limit.type ParcelWeight = Mass {    max: 30kg}

A name can be a unit by chance: the Knots scouts tie are no speed. The rule is a judgement call, so you can decline it on the type with a reason (Declining a judgement call):

example
/// Knots the scouts can tie.decline type.unit_as_number: "Knots the scouts can tie, not a speed"type Knots = Int {    min: 0}

Markdown for agents: /docs/named-types.md.Built from Jadpo main at aee2e8f.