rl_lang/docs/entries/concepts/records/
mod.rs1use crate::docs::entry::{ConceptCategory, ConceptEntry, DescriptionEntry, DescriptionKind};
2
3pub static RECORDS: ConceptEntry = ConceptEntry {
4 name: "records",
5 summary: "a named, fixed-shape collection of typed fields, declared once with `record`",
6 descriptions: &[
7 DescriptionEntry {
8 kind: DescriptionKind::Syntax,
9 title: None,
10 description: "declare a record with `record Name { Type field, Type field }`, using the same `Type name` order as function parameters; a trailing comma after the last field is allowed",
11 examples: &["record Point {\n int x,\n int y,\n}"],
12 expected_output: &[],
13 },
14 DescriptionEntry {
15 kind: DescriptionKind::Syntax,
16 title: Some("constructing a value"),
17 description: "build an instance with `Name { field: value, ... }`; fields can be given in any order but every field must be present, exactly once, with a value matching its declared type",
18 examples: &[
19 "record Point {\n int x,\n int y,\n}\n\ndec Point p = Point { x: 1, y: 2 }\ndec Point q = Point { y: 4, x: 3 }",
20 ],
21 expected_output: &[],
22 },
23 DescriptionEntry {
24 kind: DescriptionKind::Explanation,
25 title: Some("reading and writing fields"),
26 description: "access a field with `.field`, and write to it with `.field = value`; field assignment is an expression that evaluates to the assigned value, just like a variable assignment",
27 examples: &[
28 "record Point {\n int x,\n int y,\n}\n\ndec Point p = Point { x: 1, y: 2 }\nprintln(p.x) // 1\np.x = 10\nprintln(p.x) // 10",
29 ],
30 expected_output: &[],
31 },
32 DescriptionEntry {
33 kind: DescriptionKind::Explanation,
34 title: Some("records as types"),
35 description: "a record name is a type once declared: use it for `dec` bindings, function parameters and return types, or as an array element type",
36 examples: &[
37 "record Point {\n int x,\n int y,\n}\n\nfn manhattan(Point p) -> int {\n return p.x + p.y\n}\n\ndec arr[Point] path = [Point { x: 0, y: 0 }, Point { x: 1, y: 1 }]",
38 ],
39 expected_output: &[],
40 },
41 DescriptionEntry {
42 kind: DescriptionKind::Pitfall,
43 title: Some("declare before use"),
44 description: "a record must be declared earlier in the file than any place that uses it as a literal, a type annotation, or a field type; the parser reads top to bottom and only recognizes `Name { ... }` as a record literal once it has already seen `record Name { ... }`, so there's no forward-referencing between records or from earlier code to a later declaration",
45 examples: &[],
46 expected_output: &[],
47 },
48 DescriptionEntry {
49 kind: DescriptionKind::Pitfall,
50 title: Some("records are shared, not copied"),
51 description: "assigning a record value to another variable, or passing it into a function, does not copy its fields - both names refer to the same underlying data, so mutating a field through one is visible through the other; this is different from arrays, which are copied by value",
52 examples: &[
53 "record Point {\n int x,\n int y,\n}\n\ndec Point p = Point { x: 1, y: 1 }\ndec Point alias = p\nalias.x = 99\nprintln(p.x) // 99, not 1",
54 ],
55 expected_output: &[],
56 },
57 ],
58 category: ConceptCategory::Types,
59 prerequisites: &["types"],
60 pitfalls: &[
61 "records must be declared before any use, including as a type in an earlier function's signature",
62 "constructing a record requires every declared field, no more and no less; missing or extra fields are a runtime error",
63 "records have reference semantics - copies alias the same fields, unlike arrays",
64 ],
65 related: &["types", "tags", "arrays", "functions"],
66 related_stdlib: &[],
67 since: Some("v0.1.5"),
68};