Types & Atoms
LOVE-LANG's type system — atoms, type annotations, and structural schemas.
Types & Atoms
Section titled “Types & Atoms”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.
Primitive Atoms
Section titled “Primitive Atoms”The atomic building blocks of LOVE:
String
Section titled “String”Double-quoted UTF-8 strings:
greeting = "Hello, World!"multiword is "linguistics oriented programming"Number
Section titled “Number”Integer or floating-point:
count = 42ratio = 3.14159version = 0.0.1Boolean
Section titled “Boolean”active = truedisabled = falseSymbol
Section titled “Symbol”Lisp-style keyword constants — always prefixed with ::
mode = :productionstatus = :activecolor = :pinkIdentifier
Section titled “Identifier”Bareword references to other keys:
alias = my-other-valueDatetime
Section titled “Datetime”ISO 8601 formatted date/time values:
created-at = 2026-01-01T00:00:00ZType Annotations
Section titled “Type Annotations”LOVE provides two syntaxes for type annotations:
Angle-Bracket Style
Section titled “Angle-Bracket Style”name @[String] = "Alice"age @[Number] = 30active @[Boolean] = truetags @[List] = [:admin :user]Colon Style
Section titled “Colon Style”name :String = "Alice"age :Number = 30active :Boolean = trueBoth styles are equivalent and interchangeable.
Parameterized Types
Section titled “Parameterized Types”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]] ]Type Contracts (L3)
Section titled “Type Contracts (L3)”For complex structural types, define a type contract using triple brackets:
# Define the contractUserPayload = [[[ name @[String] email @[String] age @[Number] active @[Boolean] roles @[List[Symbol]]]]]
# Validate input against itvalidated = [[[ UserPayload ]]] raw-user-inputType contracts are evaluated at compile-time and produce hard errors if the data shape doesn’t match.
Inference
Section titled “Inference”LOVE-LANG can infer types from assignment:
# Type inferred as Stringgreeting = "Hello"
# Type inferred as Numbercount = 42
# Type forced via annotation (overrides inference)count @[String] = "42"Custom Types
Section titled “Custom Types”You can define custom types that extend the built-in type system:
# A custom product typeAddress = [[[ street @[String] city @[String] country @[String] postal @[String]]]]
# A custom sum type (union)Result = [[[ :ok value @[Any] :err message @[String]]]]Type Coercion
Section titled “Type Coercion”LOVE does not coerce types automatically. If you need to convert between types, use the standard library:
# String to Numbern = [[ Number.from-string "42" ]]
# Number to Strings = [[ String.from-number 42 ]]
# List to String (join)csv = [[ String.join "," ["a" "b" "c"] ]]