Lambda Data: Literals and Collections
July 2, 2026 · View on GitHub
This document covers Lambda's literal values, collection types, and expressions for composing data structures.
Related Documentation:
- Lambda Reference — Language overview and syntax
- Lambda Type System — Type hierarchy and patterns
- Lambda Expressions — Expressions and statements
Table of Contents
- Data Types Overview
- Primitive Literals
- Path Literals
- Collections
- Collection Comprehensions
- Data Composition Expressions
Data Types Overview
Lambda Script has a rich type system with both primitive and composite types:
Primitive Types
| Type | Description | Example |
|---|---|---|
null | Null/void value | null |
bool | Boolean values | true, false |
int | 56-bit signed integers | 42, -123 |
float | 64-bit floating point | 3.14, 1.5e-10 |
i8 i16 i32 | Sized signed integers | 42i8, 1000i16 |
u8 u16 u32 | Sized unsigned integers | 255u8, 60000u16 |
i64 | 64-bit signed (alias for int64) | 100i64 |
u64 | 64-bit unsigned integer | 1000u64 |
f16 f32 | Sized floating point | 0.5f16, 3.14f32 |
f64 | 64-bit float (alias for float) | 2.7f64 |
decimal | Arbitrary precision decimal | 123.456n,456.789N |
string | UTF-8 text strings | "hello" |
symbol | Interned identifiers | 'symbol' |
binary | Binary data | b'\xDEADBEEF' |
datetime | Date and time values | t'2025-01-01' |
Composite Types
| Type | Description | Example |
|---|---|---|
array | Ordered collections | [1, 2, 3] |
map | Key-value mappings | {key: "value"} |
element | Structured markup elements | <tag attr: value; content> |
range | Numeric ranges | 1 to 10 |
path | File paths and URLs | /etc.hosts, https.'api.example.com' |
function | Functions | (x) => x + 1 |
type | Type descriptors | int, string |
Special Types
any— Any type (top type)error— Error valuesnumber— Numeric union type (int | float)
Primitive Literals
Boolean and Null Literals
true
false
null
Lambda also treats empty text identifiers as null: the empty string literal
"" and the empty symbol literal '' are normalized to null. For user data,
treat string and symbol values as non-empty, with null representing the
empty case.
Numeric Literals
// Integers
42
-123
0
// Floats
3.14
-2.5
1.5e-10
1e6
inf
nan
-inf
// Decimals (arbitrary precision)
123.456n // decimal128
-789.012N // unlimited precision decimal
// Sized integers (postfix suffix)
42i8 // 8-bit signed [-128, 127]
1000i16 // 16-bit signed [-32768, 32767]
100000i32 // 32-bit signed [-$2^{31}$, $2^{31}$-1]
100i64 // 64-bit signed (alias for int64)
255u8 // 8-bit unsigned [0, 255]
60000u16 // 16-bit unsigned [0, 65535]
3000000000u32 // 32-bit unsigned [0, $2^{32}$-1]
1000u64 // 64-bit unsigned [0, $2^{64}$-1]
// Sized floats (postfix suffix)
0.5f16 // 16-bit float (half precision)
3.14f32 // 32-bit float (single precision)
2.7f64 // 64-bit float (alias for float)
Sized numeric types use a postfix suffix on numeric literals. Types i8 through u32 and f16/f32 are packed inline in the 64-bit Item representation (zero heap allocation). Types i64, u64, and f64 are heap-allocated.
Overflow behavior: Sized integer arithmetic follows a Go-like fixed-width model and wraps deterministically in the result width:
127i8 + 1i8 // -128 (wraps)
255u8 + 1u8 // 0 (wraps)
Special float values:
inf— Positive infinity-inf— Negative infinitynan— Not a number
String Literals
String literals use double quotes. Single quotes do not create strings in
Lambda; they create symbol values (see Symbol Literals).
The empty string literal "" is normalized to null; for user data, use
null to represent the empty case.
// Basic strings
"hello world"
"multiline strings
can span multiple lines"
"" // null
// Escape sequences
"line 1\nline 2"
"tab\there"
"quote: \"hello\""
Supported escape sequences:
| Escape | Character |
|---|---|
\n | Newline |
\t | Tab |
\r | Carriage return |
\\ | Backslash |
\" | Double quote |
String Indexing and Slicing
Strings are indexable by character position (0-based). Both single-character access and range slicing are supported:
let s = "hello";
s[0] // "h" — first character
s[4] // "o" — last character
s[-1] // "o" — negative index counts from end
// Range subscript: str[a to b] (inclusive both ends)
s[0 to 4] // "hello" — full string
s[1 to 3] // "ell" — substring
s[0 to 0] // "h" — single character via range
// UTF-8 aware: indices are character positions, not byte offsets
let c = "café";
c[2 to 3] // "fé" — works correctly with multi-byte characters
// Character ↔ code point conversion
ord("A") // 65 — Unicode code point of first character
chr(65) // "A" — string from Unicode code point
ord("é") // 233
chr(128512) // "😀"
Symbol Literals
Symbols are interned identifiers, often used as keys or tags:
'identifier'
'symbol-name'
'CamelCase'
'json'
'markdown'
'' // null
The empty symbol literal '' is normalized to null; for user data, use
null to represent the empty case.
Symbol vs String:
- Symbols are interned (only one copy exists in memory)
- Comparison is O(1) pointer equality
- Used for type tags, format identifiers, map keys
- Single quotes are not alternate string syntax:
'name'is asymbol,"name"is astring, and'name' == "name"isfalse - Use
string(sym)orsymbol(str)when crossing the boundary explicitly
Symbol Indexing and Slicing
Like strings, symbols support character indexing and range slicing. The result is always a symbol:
let sym = 'hello';
sym[0] // 'h' — single character (symbol)
sym[1 to 3] // 'ell' — substring (symbol)
sym[0 to 4] // 'hello' — full symbol
Binary Literals
// Hexadecimal
b'\xDEADBEEF'
b'\xA0FE af0d'
// Base64
b'\64A0FE'
b'\64A0FE gh8='
b'\64A0FE gh=='
DateTime Literals
DateTime literals use the t'...' syntax:
// Dates
t'2025' // Year only
t'2025-06' // Year-month
t'2025-04-26' // Full date
t'-1000-12-25' // Historical dates
// Times
t'10:30' // Hour:minute
t'10:30:45' // Hour:minute:second
t'10:30:45.123' // With milliseconds
t'10:30+08' // With timezone
// Date-time combinations
t'2025-05-01 10:30'
t'2025-05-01T14:30:00Z'
DateTime Sub-Types
Lambda has three datetime-related types in a sub-type hierarchy:
datetime
/ \
date time
date— Date-only values (year, month, day)time— Time-only values (hour, minute, second, millisecond)datetime— Full date and time values
// Type checking
t'2025-04-26' is date // true (date-only precision)
t'2025-04-26' is datetime // true (date <: datetime)
t'10:30:00' is time // true (time-only precision)
t'10:30:00' is datetime // true (time <: datetime)
t'2025-04-26T10:30' is date // false (has both date and time)
t'2025-04-26T10:30' is time // false (has both date and time)
DateTime Member Properties
Access datetime components using dot notation:
Date Properties:
let dt = t'2025-04-26T10:30:45.123+05:30'
dt.year // 2025 (int)
dt.month // 4 (int, 1–12)
dt.day // 26 (int, 1–31)
dt.weekday // 6 (int, 0=Sunday, 6=Saturday)
dt.yearday // 116 (int, 1–366, day of year)
dt.week // 17 (int, ISO week number 1–53)
dt.quarter // 2 (int, 1–4)
Time Properties:
dt.hour // 10 (int, 0–23)
dt.minute // 30 (int, 0–59)
dt.second // 45 (int, 0–59)
dt.millisecond // 123 (int, 0–999)
Timezone Properties:
dt.timezone // 330 (int, offset in minutes from UTC)
dt.utc_offset // '+05:30 (symbol, formatted offset)
dt.is_utc // false (bool)
Meta Properties:
dt.unix // 1745635845123 (int, Unix timestamp in milliseconds)
dt.is_date // true (bool, has date component)
dt.is_time // true (bool, has time component)
dt.is_leap_year // false (bool)
dt.days_in_month // 30 (int, days in the datetime's month)
Extraction & Conversion Properties:
dt.date // t'2025-04-26' (extract date part)
dt.time // t'10:30:45' (extract time part)
dt.utc // t'2025-04-26T05:00:45Z' (convert to UTC)
dt.local // convert to local timezone
DateTime Member Functions
Formatting:
let dt = t'2025-04-26T10:30:45'
// Custom format patterns
dt.format("YYYY-MM-DD") // "2025-04-26"
dt.format("DD/MM/YYYY") // "26/04/2025"
dt.format("hh:mm A") // "10:30 AM"
dt.format("YYYY-MM-DD hh:mm:ss") // "2025-04-26 10:30:45"
dt.format("MMM DD, YYYY") // "Apr 26, 2025"
// Predefined format names (symbol argument)
dt.format('iso') // "2025-04-26T10:30:45"
dt.format('human') // "April 26, 2025 10:30 AM"
dt.format('date') // "2025-04-26"
dt.format('time') // "10:30:45"
Format Pattern Tokens:
| Token | Meaning | Example |
|---|---|---|
YYYY | 4-digit year | 2025 |
YY | 2-digit year | 25 |
MM | 2-digit month | 04 |
M | Month without padding | 4 |
MMM | Abbreviated month name | Apr |
MMMM | Full month name | April |
DD | 2-digit day | 26 |
D | Day without padding | 26 |
ddd | Abbreviated weekday | Sat |
dddd | Full weekday | Saturday |
hh | 2-digit hour (24h) | 10 |
h | Hour without padding | 10 |
HH | 2-digit hour (12h) | 10 |
mm | 2-digit minute | 30 |
ss | 2-digit second | 45 |
SSS | 3-digit millisecond | 000 |
A | AM/PM | AM |
Z | UTC offset | +00:00 |
ZZ | UTC offset compact | +0000 |
DateTime Constructors
datetime(...) — Full Constructor:
// Current date and time
datetime() // current UTC datetime
// Parse from string
datetime("2025-04-26T10:30:00") // parse ISO 8601 string
// From components
datetime(2025, 4, 26) // date only: t'2025-04-26'
datetime(2025, 4, 26, 10, 30) // date + time: t'2025-04-26 10:30'
datetime(2025, 4, 26, 10, 30, 45) // full: t'2025-04-26 10:30:45'
// From Unix timestamp
datetime(1714100000) // from Unix timestamp (seconds)
// From map
datetime({year: 2025, month: 4, day: 26, hour: 10, minute: 30})
date(...) — Date Constructor:
// Current date
date() // same as today()
// Extract from datetime
date(some_datetime) // extract date part
// From components
date(2025, 4, 26) // t'2025-04-26'
date(2025, 4) // t'2025-04' (year-month)
date(2025) // t'2025' (year only)
// Parse from string
date("2025-04-26") // parse date string
time(...) — Time Constructor:
// Current time
time() // same as justnow()
// Extract from datetime
time(some_datetime) // extract time part
// From components
time(10, 30) // t'10:30'
time(10, 30, 45) // t'10:30:45'
time(10, 30, 45, 500) // t'10:30:45.500'
// Parse from string
time("10:30:45") // parse time string
Related Functions:
today() // current date (DATE_ONLY precision)
justnow() // current time (TIME_ONLY precision)
Path Literals
The path type represents file system paths and URLs in a unified, platform-independent way. Paths use dot notation for segment separation.
Path Syntax
// Absolute file paths (start with /)
/etc.hosts // /etc/hosts
/home.user.documents // /home/user/documents
/usr.local.bin.lambda // /usr/local/bin/lambda
// Relative paths (start with . or ..)
.config.json // ./config.json
.src.main.ls // ./src/main.ls
..parent.file // ../parent/file
// Quoted segments (for names containing dots or special chars)
/var.log.'app.log' // /var/log/app.log
.data.'my-file.json' // ./data/my-file.json
/home.user.'Documents and Settings' // Spaces in names
// HTTP/HTTPS URLs
http.api.github.com.users // http://api.github.com/users
https.example.com.data // https://example.com/data
https.httpbin.org.json // https://httpbin.org/json
// System paths
sys.env.HOME // Environment variable $HOME
sys.env.PATH // Environment variable $PATH
sys.platform // Operating system platform
// Wildcards in paths
.src.* // Single-level: all in ./src
.test.** // Recursive: all under ./test
/var.log.'*.log' // Pattern in filename
Path Schemes
| Scheme | Root Syntax | Example | Resolves To |
|---|---|---|---|
| Absolute file | / | /etc.hosts | /etc/hosts |
| Relative (current) | . | .src.main | ./src/main |
| Relative (parent) | .. | ..shared.lib | ../shared/lib |
| HTTP | http | http.'api.example.com' | http://api.example.com |
| HTTPS | https | https.'secure.api' | https://secure.api |
| System | sys | sys.env.PATH | System environment variable |
Wildcards
Paths support glob-style wildcards for pattern matching:
// Single-level wildcard (*)
.src.* // All items directly in ./src
/var.log.* // All items in /var/log
// Recursive wildcard (**)
.test.** // All items recursively under ./test
/home.user.documents.** // All files recursively
Path Concatenation
Paths can be concatenated using the ++ operator:
let base = /home.user
let config = base ++ "config" ++ "settings.json"
// Result: /home.user.config.'settings.json'
let project = .src
let file = project ++ "main.ls"
// Result: .src.'main.ls'
Path vs String
| Feature | Path | String |
|---|---|---|
| Syntax | /etc.hosts | "/etc/hosts" |
| Type | path | string |
| URL support | Native | Requires parsing |
| Wildcards | Built-in (*, **) | Manual |
| Lazy loading | Yes | No |
| Platform-independent | Yes | Separator varies |
// Path literal - cross-platform, supports URLs
let p = /home.user.config
// String - platform-specific
let s = "/home/user/config"
// Both work with input()
let data1 = input(p, 'json')
let data2 = input(s, 'json')
Path Operations
// Check existence
exists(/etc.hosts) // true or false
exists(.config.json) // true or false
// Load content
let content = input(/etc.hosts, 'text') // Load file content
let data = input(https.api.example.com.data, 'json') // Fetch URL
System Info Paths (sys.*)
The sys path scheme provides cross-platform access to system information. Values are lazily resolved — data is only fetched when accessed.
System Info Categories
| Path | Type | Description |
|---|---|---|
sys.os | Map | Operating system information |
sys.cpu | Map | CPU/processor information |
sys.memory | Map | Memory statistics |
sys.proc | Map | Process information |
sys.home | Path | User home directory |
sys.temp | Path | System temporary directory |
sys.time | Map | Current time and timezone |
sys.lambda | Map | Lambda runtime information |
sys.locale | Map | Locale settings |
OS Information (sys.os.*)
sys.os.name // "Darwin", "Linux", "Windows"
sys.os.version // "23.2.0", "6.5.0", "10.0.22631"
sys.os.kernel // Full kernel version string
sys.os.platform // "darwin", "linux", "windows"
sys.os.hostname // Machine hostname
CPU Information (sys.cpu.*)
sys.cpu.model // "Apple M2", "Intel Core i7-12700K"
sys.cpu.cores // Number of CPU cores (e.g., 8)
sys.cpu.architecture // "arm64", "x86_64"
Memory Information (sys.memory.*)
sys.memory.total // Total memory in bytes
sys.memory.free // Free memory in bytes
sys.memory.used // Used memory in bytes
Process Information (sys.proc.*)
// Current process
sys.proc.self.pid // Current process ID
sys.proc.self.ppid // Parent process ID
sys.proc.self.uid // User ID (Unix)
sys.proc.self.gid // Group ID (Unix)
sys.proc.self.argv // Command-line arguments as list
sys.proc.self.cwd // Current working directory (as Path)
sys.process // Alias for sys.proc.self
// Environment variables
sys.proc.self.env // Map of all environment variables
sys.proc.self.env.PATH // Specific variable: $PATH
sys.proc.self.env.HOME // Specific variable: $HOME
// System uptime
sys.proc.uptime // System uptime in seconds
Directory Paths (sys.home, sys.temp)
These return actual path values that can be used for file operations:
sys.home // User home directory (e.g., /Users/alice)
sys.temp // Temp directory (e.g., /tmp)
// Path composition with sys paths
let config = sys.home ++ ".config" ++ "app.json"
// Result: /Users/alice/.config.'app.json'
let tempfile = sys.temp ++ "output.txt"
// Result: /tmp.'output.txt'
Time Information (sys.time.*)
sys.time.now // Current datetime
sys.time.zone // Timezone name (e.g., "America/Los_Angeles")
sys.time.offset // UTC offset in seconds
Lambda Runtime (sys.lambda.*)
sys.lambda.version // Lambda version (e.g., "0.9.0")
sys.lambda.build // Build date
sys.lambda.features // List of enabled features
Full Example
// Build a system report
let report = {
os: sys.os.name ++ " " ++ sys.os.version,
cpu: sys.cpu.model,
cores: sys.cpu.cores,
memory_gb: sys.memory.total / (1024 ** 3),
home: sys.home,
user: sys.proc.self.env.USER
}
// Check if running on macOS
if (sys.os.platform == "darwin") {
// macOS-specific code
}
// Access environment variables
let path_dirs = split(sys.proc.self.env.PATH, ":")
Collections
Arrays
Ordered collections:
// Array creation
[1, 2, 3]
["a", "b", "c"]
[true, false, null]
// Empty array
[]
// Mixed-type arrays
[42, "hello", 3.14, true, null]
// Nested arrays
[[1, 2], [3, 4], [5, 6]]
Array Access
let arr = [10, 20, 30];
arr[0] // 10
arr[1] // 20
arr[-1] // 30 (last element)
arr[-2] // 20 (second to last)
Array Slicing
let arr = [0, 1, 2, 3, 4, 5];
arr[1 to 4] // [1, 2, 3, 4] — elements 1 to 4
Array Operations
len(arr) // 3
arr ++ [4, 5] // Concatenate: [10, 20, 30, 4, 5]
reverse(arr) // [30, 20, 10]
sort(arr) // [10, 20, 30]
unique([1,1,2,2]) // [1, 2]
Use ++ for list/array concatenation. The + operator is numeric vector
arithmetic on arrays/lists, not append:
[1, 2] + [3, 4] // [4, 6]
[1, 2] ++ [3, 4] // [1, 2, 3, 4]
Maps
Key-value mappings with structural typing:
// Map creation
{key: "value"}
{name: "Alice", age: 30, active: true}
// Mixed key types
{"string_key": 1, symbol_key: 2}
// Nested maps
{
user: {name: "Bob", email: "bob@example.com"},
settings: {theme: "dark", notifications: true}
}
// Empty map
{}
// Dynamic map construction
map([k1, v1, k2, v2, ...])
Map Access
let person = {name: "Charlie", age: 25};
person.name // "Charlie" — dot notation
person["name"] // "Charlie" — bracket notation
person.age // 25
// Safe key access, like JS optional chaining ?. (rerturn `null` if key missing)
person.address // null (key doesn't exist)
Map Operations
len(person) // 2
// Spreading a map into a new map
let wrapped = {*:person, gender: 'male'}
// {name: "Charlie", age: 25, gender: 'male'}
Elements
Structured markup elements with attributes and content, used for document processing:
// Basic element
<tag>
// Element with attributes
<div id: "main", class: "container">
// Element with content (after semicolon)
<p "Hello, world!">
// Element with attributes and content
<div class: "header"
"Page Title"
<span "Subtitle">
>
// Complex elements
<article title: "My Article", author: "John Doe"
<h1 "Introduction">
<p "This is the first paragraph.">
<p "This is the second paragraph.">
>
Element Access
let el = <div class: "main"; "content">;
el.name // 'div' (built-in: element tag name)
el.class // "main" (attribute access)
el[0] // "content" (content/child access)
Built-in Properties: Elements have a built-in .name property that returns the element's tag name as a symbol. User-defined attributes with the same name take precedence:
let custom = <div name: "custom">;
custom.name // "custom" (user-defined takes precedence)
name(custom) // 'div' (function always returns tag)
Ranges
Numeric sequences for iteration:
// Basic ranges
1 to 10 // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
0 to 5 // [0, 1, 2, 3, 4, 5]
-2 to 2 // [-2, -1, 0, 1, 2]
// Range operations
len(1 to 10) // 10
(1 to 5)[2] // 3
// Range in for loops
(for (i in 1 to 5) i * i) // [1, 4, 9, 16, 25]
Collection Comprehensions
For Expressions
For expressions iterate over collections and return new collections:
// Array iteration
(for (x in [1, 2, 3]) x * 2) // [2, 4, 6]
// Range iteration
(for (i in 1 to 5) i * i) // [1, 4, 9, 16, 25]
// Conditional iteration
(for (num in [1, 2, 3, 4, 5])
if (num % 2 == 0) num else null) // [null, 2, null, 4, null]
Extended For-Expression Clauses
For expressions support additional clauses for filtering, sorting, and limiting:
// Where clause — filter
for (x in [1, 2, 3, 4, 5] where x > 2) x
// Result: (3, 4, 5)
// Let clause — intermediate bindings
for (x in [1, 2, 3], let squared = x * x) squared + 1
// Result: (2, 5, 10)
// Order by clause — sort
for (x in [3, 1, 4, 1, 5] order by x) x
// Result: (1, 1, 3, 4, 5)
// Limit and offset — pagination
for (x in [1, 2, 3, 4, 5] limit 3 offset 1) x
// Result: (2, 3, 4)
// Combined clauses
for (x in [10, 5, 15, 20, 25, 3],
let squared = x * x
where x > 5
order by squared desc
limit 2)
squared
// Result: (625, 400)
Pipe Expressions
The pipe operator enables fluent data transformation:
// Map over collection
[1, 2, 3] | ~ * 2 // [2, 4, 6]
// Extract field from each item
users | ~.name // ["Alice", "Bob", ...]
// Chained transformations
[1, 2, 3, 4, 5]
| ~ ** 2 // square each
| ~ + 1 // add 1
// Result: [2, 5, 10, 17, 26]
// Filter with where
[1, 2, 3, 4, 5] where ~ > 3 // [4, 5]
Data Composition Expressions
Spread Operator
The spread operator * expands collections:
// Array spread
let a = [1, 2, 3]
let b = [0, *a, 4] // [0, 1, 2, 3, 4]
// Map spread (merge)
let base = {x: 1, y: 2}
let extended = {*:base, z: 3} // {x: 1, y: 2, z: 3}
// Override values
let updated = {*:base, x: 10} // {x: 10, y: 2}
When updating an existing map or record-shaped state, spread the original value first and then list the fields to change:
let next_state = {*:state, fill: "red", font_size: 12}
A fresh map literal contains exactly the fields written in the literal. It does
not copy omitted fields from any input value unless that value is explicitly
spread. Prefer the {*:base, key: value} pattern for "with" constructors and
state updates.
Concatenation
// Array concatenation
[1, 2] ++ [3, 4] // [1, 2, 3, 4]
// String concatenation
"hello" ++ " world" // "hello world"
// Path concatenation
/home.user ++ "config" // /home.user.config
For arrays/lists, + remains element-wise numeric addition. Use ++ when
the result should grow the collection.
Conditional Construction
// Conditional in collections
let items = [
1,
2,
if (condition) 3 else null, // Conditionally include
4
]
// Conditional in maps
let config = {
name: "app",
debug: if (dev_mode) true else false,
...if (has_extra) extra_config else {}
}
Nested Data Construction
// Building complex structures
let report = {
title: "Sales Report",
generated: datetime(),
summary: {
total: sum(sales | ~.amount),
count: len(sales),
average: avg(sales | ~.amount)
},
items: (for (sale in sales) {
id: sale.id,
amount: sale.amount,
formatted: "$" ++ string(sale.amount)
})
}
Type Coercion and Conversion
Implicit Coercion
Lambda performs limited implicit coercion:
// Int to float in mixed arithmetic
1 + 2.5 // 3.5 (int promoted to float)
// String concatenation coerces other types
"value: " ++ 42 // "value: 42"
Sized Integer Arithmetic
Sized integer arithmetic follows a Go-like fixed-width model:
// Same-width compact arithmetic preserves width and wraps
127i8 + 1i8 // -128i8
255u8 + 1u8 // 0u8
2147483647i32 + 1i32 // -2147483648i32
4294967295u32 + 1u32 // 0u32
// Mixed widths promote to the wider participating width
42i8 + 1000i16 // i16 result (1042)
// Mixed signed/unsigned operands promote to a type that can represent both
42i8 + 10u8 // i16 result (52)
// Sized + standard int/float promotes to standard int or float
42i8 + 100 // int result (142)
100i32 + 3.14 // float result (103.14)
// All sized types are compatible with number
42i8 is number // true
3.14f32 is number // true
Signed compact integer arithmetic wraps deterministically using two's-complement behavior in the result width. Unsigned compact integer arithmetic wraps modulo 2^N in the result width. Storage annotations keep wrapping/truncating at storage boundaries, such as compact literals, compact annotations, and compact typed-array storage.
Mixed signed/unsigned promotion uses these rules:
| Operands | Result Type | Rule |
|---|---|---|
iN + iM | i(max(N, M)) | wider signed width |
uN + uM | u(max(N, M)) | wider unsigned width |
iN + uM, where signed width can represent all unsigned values | that signed type | example: i16 + u8 -> i16 |
iN + uM, where the next signed width can represent both | next wider signed type | example: i8 + u8 -> i16, i16 + u16 -> i32, i32 + u32 -> i64 |
i64 + u64 | u64 | no signed Lambda integer can represent all u64 values |
Sized types can be passed to functions expecting int, float, or number parameters, and vice versa.
Explicit Conversion
Use conversion functions for explicit type conversion:
// To string
string(42) // "42"
string(true) // "true"
string([1, 2, 3]) // "[1, 2, 3]"
// To int
int("123") // 123
int(3.14) // 3
// To float
float("3.14") // 3.14
float(42) // 42.0
// To symbol
symbol("hello") // 'hello'
// To array
array((1, 2, 3)) // [1, 2, 3]
This document covers the foundational data types and structures in Lambda. For type system details, see Lambda Type System. For expressions and control flow, see Lambda Expressions.