Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Values and types

Values and types

Built-in types

On this page

Jadpo comes with its types built in. You use them without declaring or importing anything, and you can't reuse their names for your own types. There are three groups: the six representation types, the standard types, and a few types the language's own features need.

Representation types

The representation types say how a value is held: as a number, as text, as bytes. They are the raw material you build your own types from.

Type What it holds
Bool true or false
Int An exact 64-bit integer
Decimal An exact decimal with a required scale, the number of decimal places it keeps
Text Unicode text
Bytes A sequence of bytes
Uuid A universally unique identifier

There is no Float. Arithmetic on Decimal is exact, and its other operations are under decimal. (Numbers).

Text that arrives from outside, such as a request body, is put into Unicode's NFC form as it is read, before its rules are checked. NFC writes each character one way, so the same text always compares equal.

By default a Uuid accepts any UUID version and is kept in lowercase. The IDs Jadpo generates for new records are version 7. A named type can fix the version, which decides both what it accepts and what it generates:

example
entity Order {    id: Uuid  // generated as version 7}type PartnerRef = Uuid {    version: UuidVersion.v4  // accepts and generates only version 4}

Standard types

The standard types are one shared definition each of the things most apps need: a postal address, an amount of money, a length, a point on the earth. Without them, every app and every package would invent its own. Each has one way to build it that checks its rules, one JSON shape and one storage shape. Its fields are named, never positional: Point { latitude: ... longitude: ... }.

Their names are global, like Int, so you never import one. Their operations are grouped under a prefix such as money., units. or temporal.. There are 253 standard types, and The standard types lists every one and every operation. The groups and their best-known types are:

Group Headline types Namespaces
Money and payments Money, Currency, ExchangeRate, Price, TaxRate, Discount, Iban, BankAccount, PaymentCardNumber money
Time and calendar Instant, CalendarDate, ZonedTime, Duration, LocalTime, DateRange, RecurrenceRule, OpeningHours temporal, range
Quantities and units Length, Mass, Temperature, Speed, Energy, DataSize, Percentage, Ratio, Range<T> units, range
People and places PersonName, Username, Email, PhoneNumber, PostalAddress, PostalCode, Country, Language, Locale, Zone locale, text
Web and network Url, Slug, DomainName, HttpStatus, IpAddress, Cidr, Cookie web
Software SemanticVersion, GitRef, FilePath, TraceId, Ulid, IdempotencyKey semver
Text and documents Markdown, Html, RichText, LocalisedText markup, text
Media Colour, ImageDimensions, AspectRatio, FrameRate, VideoCodec, Timecode, ContentRating colour, media
Security and secrets Password, PasswordHash, Hash, Hmac, Jwt, PublicKey, Certificate, ApiKey, SecretText, EncryptedValue crypto, hash, random
Geospatial Point, Latitude, Polygon, Geometry, BoundingBox, Geohash geo (Geospatial)
AI TokenCount, TokenUsage, ChatMessage, ChatRole, Vector, Embedding ai (AI)
Codes and identifiers Sku, Ean13, Isbn, Barcode, TrackingNumber, Vin, VatNumber, NhsNumber, Icd10Code, IataAirport, FlightNumber, Orcid none beyond the contract below

Every standard type, by group. "(enum)" marks a fixed list of values, held as a built-in enum:

Group Types
People and contact (12) PersonName, GivenName, FamilyName, Username, Email, EmailWithName, PhoneNumber, PhoneExtension, PostalAddress, PostalCode, Uprn, Nationality (enum)
Places (10) Country (enum), CountrySubdivision (enum), Continent (enum), UnLocode, CallingCode, Language (enum), WritingScript (enum), TextDirection (enum), Locale (enum), Zone (enum)
Geospatial (17) Point, Latitude, Longitude, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, Geometry, BoundingBox, Circle, Bearing, Crs, EastingNorthing, MapTile, H3Cell, Geohash
Money, payments, banking (24) Money, Currency (enum), ExchangeRate, Price, UnitPrice, TaxRate, Discount, BasisPoints, InterestRate, PaymentCardNumber, MaskedCardNumber, CardBrand (enum), CardBin, CardExpiry, PaymentReference, InvoiceNumber, Iban, Bic, UkSortCode, UkAccountNumber, BankAccount, AbaRoutingNumber, Lei, Isin
Tax and identity numbers (12) VatNumber, TaxId, UkUtr, UkCompanyNumber, UkNationalInsuranceNumber, UsSsn, UsEin, PassportNumber, DrivingLicenceNumber, IdentityDocument, IdentityDocumentKind (enum), NhsNumber
Commerce and logistics (22) Sku, Ean13, UpcA, Isbn, Sscc, Barcode, UnitQuantity, Rating, ClothingSize, ClothingSizeSystem (enum), ShoeSize, ShoeSizeSystem (enum), Dimensions, HsCode, Incoterm (enum), TrackingNumber, Carrier, ContainerNumber, LotNumber, SerialNumber, Vin, VehicleRegistration
Time and calendar (19) Instant, CalendarDate, ZonedTime, Duration, Weekday (enum), LocalTime, LocalDateTime, Month (enum), YearMonth, Year, Quarter, IsoWeek, UtcOffset, DateRange, InstantRange, CalendarPeriod, RecurrenceRule, OpeningHours, CalendarEvent
Physical quantities (17) Length, Area, Volume, Angle, Mass, Pressure, Energy, Power, Temperature, TemperatureDifference, Speed, Frequency, Voltage, Current, Illuminance, SoundLevel, Concentration
Maths and data (8) Percentage, Ratio, Fraction, Range<T>, DataSize, Bitrate, Vector, Embedding
Health (10) BloodType (enum), Icd10Code, SnomedConcept, Dose, DosageInstruction, RouteOfAdministration (enum), HeartRate, BloodPressure, BloodGlucose, Allergen (enum)
Media and visual (16) Colour, ImageDimensions, AspectRatio, Rect, Insets, PaperSize (enum), ExifOrientation (enum), AltText, FrameRate, VideoResolution, VideoCodec, AudioCodec, Timecode, SubtitleCue, ContentRating, ContentRatingScheme (enum)
Web and network (23) Url, UrlPath, RelativeUrl, Slug, DomainName, Hostname, WebOrigin, HttpMethod (enum), HttpStatus, HttpHeaderName, FileType, UserAgent, ProblemDetails, JsonPointer, Cookie, UtmParameters, IpAddress, Cidr, NetworkPort, MacAddress, Imei, Emoji, PushToken
Software (19) SemanticVersion, VersionRange, GitRef, PackageUrl, Cve, SpdxLicence, TraceId, SpanId, TraceParent, LogLevel (enum), FilePath, FileName, RegularExpression, ContainerImage, Digest, Uuid, Ulid, IdempotencyKey, Doi
Text formats (4) Markdown, Html, RichText, LocalisedText
Security (20) Password, PasswordHash, PasswordPolicy, Hash, Hmac, Jwt, JwtClaims, Jwk, PublicKey, PrivateKey, Certificate, TotpSecret, OneTimeCode, ApiKey, SecretText, BearerToken, OAuthScope, OidcClaims, WebAuthnCredential, EncryptedValue
Travel (6) IataAirport, IcaoAirport, IataAirline, FlightNumber, CabinClass (enum), BookingReference
Other with a published standard (10) UnNumber, Orcid, CefrLevel (enum), Mpan, Mprn, EpcRating (enum), Tenure (enum), LawfulBasis (enum), Jurisdiction, ModelId
AI (4) TokenCount, TokenUsage, ChatMessage, ChatRole (enum)

The money types have a few rules of their own, because money is where mistakes cost most. Money holds a whole number of a currency's minor units, such as pence or cents, and its Currency. It never holds a decimal number of pounds. A type built on Money takes currency:, rounding:, and min: and max: in minor units. The money. operations (money.from_minor, money.minor, money.sum, money.allocate) build amounts and work them out. A named type for an amount in pounds:

example
type Sterling = Money {    currency: Currency.gbp    min: 0    rounding: Rounding.half_even}

An amount in another currency doesn't compile where a Sterling is wanted. Use Int for counts and sizes, and Money for amounts of money. Money and payments has the rest.

What every standard type does

Every standard type meets the same contract, so one operation works across all of them:

  • Construct and validate. From its parts (PostalCode(raw), or money.from_minor for Money), and from text with text.parse(raw, as: T). Each failure is named by the rule it breaks, and malformed means the text isn't that type at all.
  • Show and write. text.format(value, locale:) gives text for people, and text.from(value) gives the canonical text (E.164, ISO codes, ISO 8601) that text.parse reads back. A type with no single text form, such as PostalAddress, can't be asked for one.
  • Storage. One shape: a column, or named columns for an object (Money's two).
  • JSON. One shape, read and written by json.read, json.write and every route.
  • Equality and order. == works on every type; < and sort_by work where order means something (quantities of one kind, Money of one currency, times, SemanticVersion, Percentage).

A type that copies a standard type under another name is the error type.standard_exists. For example, a Booking with only a start and an end, each an Instant, is an InstantRange. When the copy is deliberate, you can decline the error with a reason. A declaration with the same name as a standard type is type.standard_clash. Both are explained under The standard types and A release that adds a standard type.

What the standard types do

Standard types come with their own arithmetic, units and rules, so you write a sum as you would on paper and it is checked as strictly as a call. Which operators work on which types is set by the standard operator table.

A sum of lengths can mix units, and the result is a Length. Inches are written inch, because m means minutes:

example
type Shelf = Length {}/// A metre, 2.3 inches and 3 centimetres, then 20% of that: a `Length`.function fifth_of(base: Shelf) -> Shelf {    return Shelf((base + 2.3inch + 3cm) * 20%)}
example
test "units mix within a kind" {    assert fifth_of(Shelf(1metre)) == Shelf((1metre + 2.3inch + 3cm) * 20%)}

Mix up a unit and the compiler says so. Here 1m is one minute, a Duration, which can't be added to a Length:

example
type Shelf = Length {}/// `m` is minutes, so this adds a `Duration` to a `Length`.function mistaken(base: Shelf) -> Shelf {    return Shelf((1m + 2.3inch + 3cm) * 20%)}
text
error: A duration and a quantity can't be added: a `Duration` and a `Length` are different kinds --> main.jadpo:5:19  |5 |     return Shelf((1m + 2.3inch + 3cm) * 20%)  |                   ^^^^^^^^^^^^ different kinds  reason: `+` works within one kind of quantity, in any of its units; a `Duration` and a `Length` are different kinds, so the sum means nothing.  next: Use values of one kind, or a product or quotient the table defines (agent)  rule: type.arithmetic_operand  help: https://jadpo.dev/docs/errors/type.arithmetic_operandcheck failed: 1 error, 1 file

Money is a whole number of minor units in one currency, so the operator table allows less on it. A percentage scales it: price * 120% adds 20% VAT. To share an amount out, use money.split, which loses no penny: £10.00 three ways is £3.34, £3.33 and £3.33. Dividing, as in price / 3, is refused with type.money_split, which suggests money.split (Money operations):

example
type CakePrice = Money {    currency: Currency.gbp    min: 0}type Payment = Money {}/// A price with 20% VAT added.function with_vat(price: CakePrice) -> CakePrice {    return CakePrice(price * 120%)}/// A bill shared three ways, every penny to someone.function shares(total: CakePrice) -> List<Payment> {    return list.map(money.split(total, 3), share -> Payment(share))}
example
test "VAT and sharing lose nothing" {    var price: CakePrice = CakePrice(money.from_minor(1000, Currency.gbp))    assert with_vat(price) == money.from_minor(1200, Currency.gbp)    assert shares(price) == [        Payment(money.from_minor(334, Currency.gbp)),        Payment(money.from_minor(333, Currency.gbp)),        Payment(money.from_minor(333, Currency.gbp))    ]}

price + 20% could mean two things, so it is refused. Write price * 120% instead:

example
type CakePrice = Money {    currency: Currency.gbp}/// Twenty percent added to a price: ambiguous, so refused.function more(price: CakePrice) -> CakePrice {    return CakePrice(price + 20%)}
text
error: `CakePrice` and a percentage can't be added: it could mean two things --> main.jadpo:7:22  |7 |     return CakePrice(price + 20%)  |                      ^^^^^^^^^^^ an amount and a percentage  reason: `price + 20%` could mean the amount raised by 20% of itself, or 20% of some other amount; the standard operator table refuses it rather than guess. A percentage scales money by `*`.  next: Write `price * 120%`, or `price + price * 20%`, whichever is meant (agent)  rule: type.arithmetic_operand  help: https://jadpo.dev/docs/errors/type.arithmetic_operandcheck failed: 1 error, 1 file

Adding two amounts whose types are in different currencies is a compile error:

example
type CakePrice = Money {    currency: Currency.gbp}type EuroPrice = Money {    currency: Currency.eur}/// A cake in pounds and a delivery charged in euros.function delivered(price: CakePrice, delivery: EuroPrice) -> CakePrice {    return CakePrice(price + delivery)}
text
error: `CakePrice` and `EuroPrice` can't be added: they're in different currencies --> main.jadpo:11:22   |11 |     return CakePrice(price + delivery)   |                      ^^^^^^^^^^^^^^^^ GBP and EUR  reason: `CakePrice` is in GBP and `EuroPrice` in EUR, as their types or the calls that made them fix; amounts are added only in one currency.  next: Use two amounts in the same currency (agent)  rule: type.arithmetic_operand  help: https://jadpo.dev/docs/errors/type.arithmetic_operandcheck failed: 1 error, 1 file

Dates, times and temperatures work the same way. A CalendarDate plus a one-month CalendarPeriod stops at the last day of the month when the day doesn't exist there. Instant - Instant gives a Duration. Subtracting one temperature from another gives a TemperatureDifference:

example
type DeliveryDay = CalendarDate {}type SeenAt = Instant {}type Gap = Duration {}/// A day a month on: the 31st of January gives the last day of February.function month_on(day: DeliveryDay) -> DeliveryDay {    return DeliveryDay(        day + CalendarPeriod {            years: 0            months: 1            days: 0        }    )}/// How long between two moments.function between(start: SeenAt, end: SeenAt) -> Gap {    return Gap(end - start)}
example
test "calendar and clock arithmetic" {    assert month_on(DeliveryDay("2026-01-31")) == DeliveryDay("2026-02-28")    assert between(SeenAt("2026-10-25T09:00:00Z"), SeenAt("2026-10-25T11:30:00Z")) == Gap(150m)    assert 25degC - 20degC == units.of(5, TemperatureDifferenceUnit.kelvin)}

Other built-in types

These types belong to features of the language. Each row links the page that covers the feature.

Kind Types Notes
Containers List<T>, Set<T>, Map<K, V> Described below.
Translation PluralCount, TextDirection, TranslationReview PluralCount is a whole number that picks a message's plural form, used directly as a Message field; TextDirection is a locale's direction, .left_to_right or .right_to_left, which locale.direction(value) gives; TranslationReview is .none or .required, the review: of translations: in application { } (What the compiler checks of translations).
Files File, FileUpload, UploadSlot, FileContents A stored file (its key, name, size and type) as an entity field; the token of a finished upload in an Input; the signed address, or addresses for each part, an upload goes to; and what store.read returns, a file's bytes for passing on (to a provider, a PDF service, an email), which the format helpers do not accept (Files).
Batches BatchRun, BatchProgress, RowProblem, ImportSummary, ExportSummary, CsvFormat A batch run, as the batch helpers return it and as an entity field can store it; its progress from batches.status; one bad row or failed item, without its value; what finished: receives after reading (or batches.each) and after writing, the latter holding the stored File; and who a CSV is written for, CsvFormat.spreadsheet or .standard (Batches).
Services SearchText, OAuthGrant, AnyObject What people type into a search box (Search); a connection's credential held for each owner record, OAuthGrant { owner: ... }, written only in a connection's credential: and never readable by code (Acting for each user: OAuth grants); and, only as a package operation's input field, any of the app's object types, sent in its JSON form (Postmark's template variables, Stripe's metadata).
Bases Object, Enum, Input, Output Used only after = in a type declaration. Other features add bases the same way: Failure (Failures), Event (Declaring an event), EmailMessage (Email), Document, a template rendered to HTML or PDF (Documents), and Message, a translated message whose fields are its placeholders (Translations as messages).
Decoding DecodeProblem field: Text, a field's path with list positions as numbers, and rule: Text; never the value. It is what a failure mapped from json.read's mismatch receives in its problem field, and only the runtime builds one.
Nothing Unit What an action returns when it returns nothing.

The batch types' fields, as Batches uses them:

Type Fields
BatchRun id: Uuid; storable in an entity field, so an app can keep the run on its own import record
BatchProgress items_done: Int, estimated_total: Int? (from the file's size or the query's count), problems: Int (so far), state: BatchState (.running, .finished, .failed, .cancelled)
RowProblem row: Int (as a spreadsheet numbers it), column: Text, rule: Text (the rule's code, as a refused request's problems give it, HTTP); never the value
ImportSummary items: Int, items_with_problems: Int, problems: List<RowProblem>
ExportSummary The same three fields, and file: File, the file written

The literals, values written straight into code, are true and false, whole numbers (25, -3), decimals (1.25), strings ("Hello", with \", \\, \n, \r and \t escapes) and none.

Markdown for agents: /docs/built-in-types.md.Built from Jadpo main at a707efb.