Gleam Tuples
A tuple groups a fixed number of values of different types into one unit. Tuples are lightweight and need no type declaration — you create them instantly with the #() syntax. They are perfect for returning multiple values from a function or grouping related data without defining a full record type.
Creating Tuples
let point = #(10, 20)
let person = #("Aditya", 28, True)
let rgb = #(255, 128, 0)
let pair = #("key", 42)
Tuple Memory Diagram
──────────────────────────────────────────────────
let person = #("Aditya", 28, True)
┌──────────┬────┬───────┐
│ "Aditya" │ 28 │ True │
└──────────┴────┴───────┘
position 0 1 2
Tuple positions start at 0. Each position holds a value of any type. The tuple's type captures the type at each position — #(String, Int, Bool) in the example above.
Accessing Tuple Elements
Use pattern matching to extract elements from a tuple:
let point = #(40, 75)
let #(x, y) = point
// x = 40, y = 75For two-element tuples, the standard library provides helper functions:
import gleam/pair
let coords = #(40, 75)
let x = pair.first(coords) // 40
let y = pair.second(coords) // 75Tuples in Function Returns
Functions can only return one value. Wrap multiple values in a tuple to return them together:
pub fn min_max(a: Int, b: Int, c: Int) -> #(Int, Int) {
let minimum = case a < b && a < c { True -> a, False -> case b < c { True -> b, False -> c } }
let maximum = case a > b && a > c { True -> a, False -> case b > c { True -> b, False -> c } }
#(minimum, maximum)
}
pub fn main() {
let #(lo, hi) = min_max(8, 3, 15)
// lo = 3, hi = 15
}
Return Tuple Flow
──────────────────────────────────────────────────
min_max(8, 3, 15)
│
└── computes minimum = 3
└── computes maximum = 15
└── returns #(3, 15)
Caller:
let #(lo, hi) = min_max(8, 3, 15)
// lo = 3, hi = 15
Tuple Types
The type of a tuple lists the types at each position:
let a: #(Int, String) = #(1, "one")
let b: #(Bool, Float, Int) = #(True, 3.14, 42)
let c: #(String, String) = #("hello", "world")Discarding Tuple Elements
Use _ to ignore specific elements you do not need:
let person = #("Priya", 30, "Engineer")
let #(name, _, role) = person
// name = "Priya", role = "Engineer", age ignoredTuples in Pattern Matching
Tuples work naturally with case expressions for multi-dimensional decisions:
pub fn format_coordinates(point: #(Int, Int)) -> String {
case point {
#(0, 0) -> "Origin"
#(x, 0) -> "On X-axis: " <> int.to_string(x)
#(0, y) -> "On Y-axis: " <> int.to_string(y)
#(x, y) -> "(" <> int.to_string(x) <> ", " <> int.to_string(y) <> ")"
}
}When to Use Tuples vs Records
Tuples vs Records — Decision Guide
──────────────────────────────────────────────────
Situation │ Use
─────────────────────────────────┼──────────────
Temporary, short-lived grouping │ Tuple
Returning 2–3 values from a fn │ Tuple
Data with named fields (clarity) │ Record
Data shared across many functions│ Record
More than 3 fields │ Record
Tuples shine for small, local groupings where defining a full type would be overkill. When data grows or travels across functions, a named record type (covered in the next topic) provides better documentation.
Practical Example — Quotient and Remainder
import gleam/io
pub fn divide_with_remainder(dividend: Int, divisor: Int) -> #(Int, Int) {
let quotient = dividend / divisor
let remainder = dividend % divisor
#(quotient, remainder)
}
pub fn main() {
let #(q, r) = divide_with_remainder(17, 5)
io.debug(q) // 3
io.debug(r) // 2
// 17 = 5×3 + 2
}
Divide 17 by 5
──────────────────────────────────────────────────
17 ÷ 5
█████ █████ █████ ██ ← 17 items
│ │ │ │
└─────┴─────┘ └── remainder = 2
3 groups of 5
Result: #(3, 2) → quotient = 3, remainder = 2
Nested Tuples
let matrix_cell = #(#(2, 3), "value")
let #(#(row, col), data) = matrix_cell
// row = 2, col = 3, data = "value"Key Points
Tuple Summary
──────────────────────────────────────────────────
1. Created with #(value1, value2, ...)
2. Fixed length — cannot add or remove elements
3. Elements can be different types
4. Access by pattern matching or pair.first/second
5. Type includes the type at each position
6. Use _ to ignore elements you don't need
7. Best for small, local groupings
Tuples are the simplest composite type in Gleam. They hold multiple values together without any overhead — no field names, no declarations, no boilerplate. Reach for them whenever you need a quick way to group two or three related values.
