Skip to content

Types and Values

Sentrie provides a robust type system that includes primitive types, collection types, and user-defined shapes. The type system is enhanced by a powerful constraint system that allows you to validate values against specific rules.

Sentrie supports five fundamental primitive types:

TypeDescription
numberNumeric values
stringText strings
trinaryTrinary values (true / false / unknown)
boolBoolean values (true / false) - a special case of trinary
documentArbitrary JSON-like objects
let u: number = 50
let u: number = 50.5
let u: string = "hello"
let u: bool = true
let u: document = { "name": "John", "age": 30 }

Collections allow you to work with groups of related values:

TypeDescription
list[T]Lists of type T
dict[T]Maps with string keys and type T values
record[T1, T2, ...]Tuples with specific types
let u: list[number] = [1, 2, 3]
let u: dict[number] = { "one": 1, "two": 2, "three": 3 }
let u: record[string, number, bool] = ["one", 1, true]

Sentrie supports type-level nullability with a ? suffix on type references.

  • string? -> value may be null or a string
  • list[string]? -> list itself may be null
  • dict[string?] -> dict values may be null
  • Person? -> shape value may be null
let middleName: string? = null
let tags: list[string]? = null
let attrs: dict[string?] = {"nickname": null}

T? means nullable value. This is different from optional bindings (for example, field? in shapes/facts), which control whether a key may be absent.

You can access collection elements using the [index] syntax. The index must be a string for dicts and a number for lists and records.

let u: list[number] = [1, 2, 3]
let first: number = u[0]
let u: dict[number] = { "one": 1, "two": 2, "three": 3 }
let first: number = u["one"]

For dicts, you can also access elements using the . syntax.

let u: dict[number] = { "one": 1, "two": 2, "three": 3 }
let first: number = u.one

You can convert between types using the cast .. as construct. The result is validated against the new type constraints before returning the result.

let u: number = cast "50" as number
let u: string = cast 50 as string
let u: bool = cast "true" as bool
let u: document = cast { "name": "John", "age": 30 } as document