Data
data declares read-only data: the declaration is the instance, deeply immutable, fully validated at compile time. A good fit for data written directly into code: config tables, tuning values, static atlas descriptions.
One Name, Two Roles: Type and Value
public data Item { label: "text", }
public data Sword
{
...Item,
name: "iron sword",
atk: 10 + 5,
tags: ["iron", "starter"],
}
func main() -> int
{
print(Sword.name, Sword.atk);
print(Sword.label);
return 0;
}iron sword 15
text- In type position,
Swordis a nominal type; in value position it is the canonical instance. Entries are comma-separated and support constant arithmetic folding (10 + 5yields 15) and frozen lists. ...Basespreads another data declaration.- Entries are separated by commas; the trailing comma before
}is optional.
Literals in Expression Position
A data { ... } written in expression position is a runtime literal section, likewise frozen on construction, which suits assembling one-off data locally:
val d = data { x: 5, y: 6, label: "local" };
val moved = d with { x: 50 };
print(d.x, moved.x, moved.label);5 50 localOnly a data at the start of an expression followed by { is a literal; everywhere else data remains an ordinary identifier.
with: The Only Mutation Channel
Every mutation surface of a data value is closed off; the only way to change the data is to derive a new value with with:
val upgraded = Sword with { atk: 99 };
print(upgraded.name, upgraded.atk, Sword.atk);iron sword 99 15The original Sword is unchanged: with produces a brand-new frozen instance. When you need a mutable copy, ToMutable() on a frozen container is the only escape hatch: it converts to the matching mutable container type, and the original data is unaffected:
var mut = Sword.tags.ToMutable();
mut.Add("new");
print(mut.Count, Sword.tags.Count, Sword.name);3 2 iron swordValue Domain
Entry values accept: the literal family, enum / flags qualified-name constants, nested anonymous records, frozen lists, references to other data, and vector construction folds. Rejected: null, non-constants, function values and mutable references, class / struct instances.
Notes
- The name declared by a data declaration cannot be
newed: instances come only from the canonical instance slot andwithderivation. - A
data { ... }in expression position is a runtime literal section, frozen on construction, suited to local assembly. - Every data value implicitly widens to the built-in supertype
Data.
