1Records
2-------
3A record is a set of fields (name/value pairs).
4If ``R`` is the record value ``{a:1,b:2}``,
5then ``R.a`` is ``1``, the value of field ``a``.
6
7Records are used to represent:
8
9* sets of labeled arguments in a function call;
10* geometric shapes (each field is a shape attribute);
11* general application data structures;
12* libraries or modules, where the fields represent APIs, not data;
13* module namespaces, where the fields are modules.
14
15Record Constructors
16~~~~~~~~~~~~~~~~~~~
17A record constructor is an expression that constructs a record value.
18There are three syntaxes:
19
201. Dynamic records like ``{a:1, b:2}``.
212. Scoped records like ``{a=1, b=2}``.
223. Directory records. For example, a directory ``foo`` contains two files
23   named ``a.curv`` and ``b.curv``. The expression ``file "foo"``
24   reads this directory and returns a record value containing
25   fields ``a`` and ``b``.
26
27**Dynamic records** permit you to construct a record value dynamically.
28The set of field names is determined at run time using program logic, which
29can include conditionals, local variables and loops.
30
31A dynamic record constructor is a list of field generators
32(such as ``name: value``), separated by commas and enclosed by braces.
33For example::
34
35    {}
36    {a: 1}
37    {a: 1, b: 2}
38
39The full syntax is defined in `Generators`_.
40
41Unlike scoped records, dynamic records do not introduce a scope
42(field specifiers can't refer to one another).
43This means you can write a dynamic record that references local variables
44with the same names as the field names, like this: ``{x:x, y:y}``.
45This makes dynamic records the preferred syntax for specifying labeled
46arguments in a function call. For example::
47
48    rotate {angle: 45*deg, axis: Z_axis} cube
49
50A **scoped record** is a set of mutually recursive definitions,
51separated by commas or semicolons, and enclosed in braces.
52See `Definitions`_ for more details.
53
54The set of field names in a scoped record is determined at compile time.
55The definitions can refer to one another, but their order doesn't matter,
56and you can define recursive functions. Duplicate definitions cause
57an error.
58
59Scoped record syntax is used to define
60modules, where the fields represent APIs, not data.
61See ``lib/curv/*.curv`` in the source tree for examples.
62Note that these source files begin and end with ``{`` and ``}``.
63
64**Directory syntax** is used to define a module namespace,
65where each module in the namespace is represented by a separate
66source file or directory.
67See `File_Import`_ for details.
68
69.. _`Generators`: Generators.rst
70.. _`Definitions`: Definitions.rst
71.. _`File_Import`: File_Import.rst
72
73The Spread Operator
74~~~~~~~~~~~~~~~~~~~
75Within a dynamic record constructor, fields are processed left to right.
76If the same field name is specified more than once, then the last occurrence
77wins. For example::
78
79    {a: 1, b: 2, c: 3, a: 999}
80
81evaluates to ``{a: 999, b: 2, c: 3}``.
82
83The **spread operator** ``...r`` copies the fields from the record ``r``
84into the record being constructed. Using the left-to-right override
85semantics, you can create an updated copy of an existing record ``r``,
86defining default values for missing fields, and overriding existing fields.
87
88* ``{x: 0, ... r}`` -- The same as record ``r``, except that if field ``x`` is
89  not defined, then it defaults to ``0``.
90* ``{... r, x: 0}`` -- The same as record ``r``, extended with field ``x``,
91  with ``x:0`` overriding any previous binding.
92
93Within a list constructor, ``...r`` copies the fields of the record ``r``
94into the list, converting each field into a ``[symbol,value]`` pair.
95So ``[...r]`` converts a record to a field list. For example::
96
97    [... {a: 1, b: 2}]
98
99evaluates to ``[[#a,1], [#b,2]]``.
100
101Within a dynamic record constructor, ``...fieldlist`` copies the fields
102from a fieldlist into the record being constructed.
103So ``{...fieldlist}`` converts a fieldlist to a record.
104
105The spread operator is one example of generator syntax.
106See `Generators`_ for full details.
107
108Record Operations
109~~~~~~~~~~~~~~~~~
110In the following examples, ``R`` is a local variable
111containing the record value ``{a: 1, b: 2}``.
112
113``is_record value``
114  True if the value is a record, false otherwise.
115  For example, ``is_record R`` is ``#true``.
116
117``record . identifier``
118  The value of the field named by ``identifier``.
119  For example, ``R.a`` is ``1``.
120
121``record .[ symbolExpr ]``
122  The value of the field named by the symbol after evaluating symbolExpr.
123  This allows the field name to be computed at run time.
124  For example, ``R.[#a]`` is ``1``.
125  See `Trees`_ for more information about querying data structures.
126
127``recordVariable . identifier := newValue``
128  Given a local variable containing a record value,
129  update the variable to contain a copy of the record value
130  where the field named ``identifier`` has the value ``newValue``.
131  For example, after executing::
132
133     R.a := 99
134
135  then the variable ``R`` will contain ``{a: 99, b: 2}``.
136
137``recordVariable .[ symbolExpr ] := newValue``
138  Given a local variable containing a record value,
139  update the variable to contain a copy of the record value
140  where the field named by the symbol ``symbolExpr`` has the value ``newValue``.
141  For example, after executing::
142
143     R.[#a] := 99
144
145  then the variable ``R`` will contain ``{a: 99, b: 2}``.
146  See `Trees`_ for more information about updating data structures.
147
148``defined (record . identifier)``
149  True if a field named ``identifier`` is defined by ``record``, otherwise false.
150  For example, ``defined(R.a)`` is true and ``defined(R.foo)`` is false.
151
152``defined (record .[ symbolExpr ])``
153  Test the field named by the symbol after evaluating symbolExpr.
154  If the field exists, return true, otherwise false.
155  This allows the field name to be computed at run time.
156  For example, ``defined(R.[#a])`` is true and ``defined(R.[#foo])`` is false.
157
158``fields record``
159  The field names defined by ``record`` (as a list of symbols).
160  For example, ``fields R`` returns ``[#a, #b]``.
161
162``merge listOfRecords``
163  Merge all of the fields defined by the records in ``listOfRecords``
164  into a single record. If the same field is defined more than once,
165  the last occurrence of the field wins.
166  Same as::
167
168    {for (r in listOfRecords) ...r}
169
170.. _`Trees`: Trees.rst
171