Open Record Types
This example shows how to write functions that accept any record with a name field. greet only reads that field, while rename changes it and preserves whatever other fields the caller supplied.
greet : { name : Str, ..others } -> Str greet = |person| "Hello, ${person.name}!" rename : { name : Str, ..others }, Str -> { name : Str, ..others } rename = |person, name| { ..person, name } expect greet({ name: "Sam" }) == "Hello, Sam!" expect greet({ name: "Lee", age: 30 }) == "Hello, Lee!" expect rename({ name: "Sam", age: 30 }, "Samantha") == { name: "Samantha", age: 30 }
The ..others part of the annotation makes the record open to additional fields. Using the same ..others in rename’s input and output preserves those fields and their types, so the caller’s age survives the rename.
Output
Run this from the directory that has main.roc in it:
$ roc test main.roc All (3) tests passed in 6.2 ms.
Validated with Roc nightly-2026-10-29-a0a9fc2.