Skip to content

Types

ISL has a rich type system with built-in primitive types, collection types, and the ability to define custom constrained types.

Primitive types

TypeDescriptionExample
BooleanTrue or falsetrue, false
IntArbitrary precision integer42, -1
DecimalDecimal number with precision99.99, 0.01
StringUTF-8 string"hello"
BytesRaw byte sequenceBinary data

Built-in semantic types

These types carry semantic meaning and built-in validation rules:

TypeDescriptionFormat
UUIDRFC 4122 UUID550e8400-e29b-...
EmailRFC 5322 email addressuser@example.com
URLRFC 3986 URLhttps://example.com
PhoneE.164 phone number+1234567890
TimestampUnix timestamp with nanoseconds1706745600
DurationTime duration1s, 500ms, 2h
MoneyCurrency amount with precision99.99 USD
Percentage0-100 value with precision85.5
RegexRegular expressionPattern string

Collection types

TypeDescriptionExample
List<T>Ordered sequenceList<String>
Map<K, V>Key-value mappingMap<String, Int>
Set<T>Unique unordered elementsSet<UUID>
Optional<T>Value that may be absentOptional<Email> or Email?
Result<T, E>Success or error valueResult<User, Error>

Optional shorthand

Use ? suffix as shorthand for Optional<T>:

entity User {
id: UUID
email: Email
nickname: String? // Same as Optional<String>
avatar_url: URL? // Same as Optional<URL>
}

Custom type declarations

Define custom types with constraints applied to a base type:

// String with pattern constraint
type Email = String {
pattern: "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
max_length: 254
}
// Decimal with range constraint
type Money = Decimal {
min: 0
precision: 2
}
// Integer with minimum
type PositiveInt = Int {
min: 1
}
// String with length constraint
type Username = String {
min_length: 3
max_length: 32
pattern: "^[a-zA-Z0-9_]+$"
}
// Constrained collection
type NonEmptyList<T> = List<T> {
min_length: 1
}

Available constraints

String constraints:

ConstraintDescription
min_lengthMinimum string length
max_lengthMaximum string length
patternRegular expression pattern

Numeric constraints:

ConstraintDescription
minMinimum value (inclusive)
maxMaximum value (inclusive)
precisionDecimal precision

Collection constraints:

ConstraintDescription
min_lengthMinimum number of elements
max_lengthMaximum number of elements

Enumeration types

Define a finite set of named values:

enum PaymentStatus {
PENDING
PROCESSING
COMPLETED
FAILED
REFUNDED
}
enum Currency {
USD
EUR
GBP
JPY
}

Use enums in entity fields:

entity Payment {
id: UUID [immutable, unique]
status: PaymentStatus
currency: Currency
}

Type usage in entities

entity Order {
id: UUID [immutable, unique]
customer_id: UUID [immutable]
items: List<OrderItem>
total: Money
status: OrderStatus
notes: String?
metadata: Map<String, String>
tags: Set<String>
created_at: Timestamp [immutable]
invariants {
total >= 0
items.length > 0
}
}

Type usage in behaviors

behavior CreateOrder {
input {
customer_id: UUID
items: List<OrderItem> // Collection of items
coupon_code: String? // Optional input
}
output {
success: Order
errors {
EMPTY_CART { when: "No items provided" }
}
}
preconditions {
items.length > 0
all(item in items: item.quantity > 0)
}
postconditions {
success implies {
result.total == sum(item in items: item.price * item.quantity)
}
}
}

Type compatibility

ISL uses structural typing for custom types. A value of type PositiveInt is compatible with Int because PositiveInt is a constrained Int. The reverse is not true — an arbitrary Int may not satisfy the constraints of PositiveInt.