Skip to content

Types & Atoms

LOVE-LANG's type system — atoms, type annotations, and structural schemas.

LOVE-LANG has a rich, extensible type system built from the ground up. Every value in LOVE is a typed atom or a typed list.


The atomic building blocks of LOVE:

Double-quoted UTF-8 strings:

greeting = "Hello, World!"
multiword is "linguistics oriented programming"

Integer or floating-point:

count = 42
ratio = 3.14159
version = 0.0.1
active = true
disabled = false

Lisp-style keyword constants — always prefixed with ::

mode = :production
status = :active
color = :pink

Bareword references to other keys:

alias = my-other-value

ISO 8601 formatted date/time values:

created-at = 2026-01-01T00:00:00Z

LOVE provides two syntaxes for type annotations:

name @[String] = "Alice"
age @[Number] = 30
active @[Boolean] = true
tags @[List] = [:admin :user]
name :String = "Alice"
age :Number = 30
active :Boolean = true

Both styles are equivalent and interchangeable.


Types can be parameterized with sub-types:

ids @[List[Number]] = [1 2 3 4 5]
names @[List[String]] = ["Alice" "Bob" "Carol"]
init @[List[String]] = [#! [args :List[String]] ]

For complex structural types, define a type contract using triple brackets:

# Define the contract
UserPayload = [[[
name @[String]
email @[String]
age @[Number]
active @[Boolean]
roles @[List[Symbol]]
]]]
# Validate input against it
validated = [[[ UserPayload ]]] raw-user-input

Type contracts are evaluated at compile-time and produce hard errors if the data shape doesn’t match.


LOVE-LANG can infer types from assignment:

# Type inferred as String
greeting = "Hello"
# Type inferred as Number
count = 42
# Type forced via annotation (overrides inference)
count @[String] = "42"

You can define custom types that extend the built-in type system:

# A custom product type
Address = [[[
street @[String]
city @[String]
country @[String]
postal @[String]
]]]
# A custom sum type (union)
Result = [[[
:ok value @[Any]
:err message @[String]
]]]

LOVE does not coerce types automatically. If you need to convert between types, use the standard library:

# String to Number
n = [[ Number.from-string "42" ]]
# Number to String
s = [[ String.from-number 42 ]]
# List to String (join)
csv = [[ String.join "," ["a" "b" "c"] ]]