Skip to content

Commit 82bb5a0

Browse files
committed
RFC: Clarify the relationships between various kinds of structs and variants
1 parent ee281d7 commit 82bb5a0

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

text/0000-adt-kinds.md

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
- Feature Name: clarified_adt_kinds
2+
- Start Date: 2016-02-07
3+
- RFC PR: (leave this empty)
4+
- Rust Issue: (leave this empty)
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Provide a simple model describing three kinds of structs and variants and their relationships.
10+
Provide a way to match on structs/variants in patterns regardless of their kind (`S{..}`).
11+
Permit tuple structs and tuple variants with zero fields (`TS()`).
12+
13+
# Motivation
14+
[motivation]: #motivation
15+
16+
There's some mental model lying under the current implementation of ADTs, but it is not written
17+
out explicitly and not implemented completely consistently.
18+
Writing this model out helps to identify its missing parts.
19+
Some of this missing parts turn out to be practically useful.
20+
This RFC can also serve as a piece of documentation.
21+
22+
# Detailed design
23+
[design]: #detailed-design
24+
25+
The text below mostly talks about structures, but almost everything is equally applicable to
26+
variants.
27+
28+
## Braced structs
29+
30+
Braced structs are declared with braces (unsurprisingly).
31+
32+
```
33+
struct S {
34+
field1: Type1,
35+
field2: Type2,
36+
field3: Type3,
37+
}
38+
```
39+
40+
Braced structs are the basic struct kind, other kinds are built on top of them.
41+
Braced structs have 0 or more user-named fields and are defined only in type namespace.
42+
43+
Braced structs can be used in struct expressions `S{field1: expr, field2: expr}`, including
44+
functional record update (FRU) `S{field1: expr, ..s}`/`S{..s}` and with struct patterns
45+
`S{field1: pat, field2: pat}`/`S{field1: pat, ..}`/`S{..}`.
46+
In all cases the path `S` of the expression or pattern is looked up in the type namespace.
47+
Fields of a braced struct can be accessed with dot syntax `s.field1`.
48+
49+
Note: struct *variants* are currently defined in the value namespace in addition to type namespace,
50+
there are no particular reasons for this and this is probably temporary.
51+
52+
## Unit structs
53+
54+
Unit structs are defined without any fields or brackets.
55+
56+
```
57+
struct US;
58+
```
59+
60+
Unit structs can be thought of as a single declaration for two things: a basic struct
61+
62+
```
63+
struct US {}
64+
```
65+
66+
and a constant with the same name
67+
68+
```
69+
const US: US = US{};
70+
```
71+
72+
Unit structs have 0 fields and are defined in both type (the type `US`) and value (the
73+
constant `US`) namespaces.
74+
75+
As a basic struct, a unit struct can participate in struct expressions `US{}`, including FRU
76+
`US{..s}` and in struct patterns `US{}`/`US{..}`. In both cases the path `US` of the expression
77+
or pattern is looked up in the type namespace.
78+
Fields of a unit struct could also be accessed with dot syntax, but it doesn't have any fields.
79+
80+
As a constant, a unit struct can participate in unit struct expressions `US` and unit struct
81+
patterns `US`, both of these are looked up in the value namespace in which the constant `US` is
82+
defined.
83+
84+
Note 1: the constant is not exactly a `const` item, there are subtle differences, but it's a close
85+
approximation.
86+
Note 2: the constant is pretty weirdly namespaced in case of unit *variants*, constants can't be
87+
defined in "enum modules" manually.
88+
89+
## Tuple structs
90+
91+
Tuple structs are declared with parentheses.
92+
```
93+
struct TS(Type0, Type1, Type2);
94+
```
95+
96+
Tuple structs can be thought of as a single declaration for two things: a basic struct
97+
98+
```
99+
struct TS {
100+
0: Type0,
101+
1: Type1,
102+
2: Type2,
103+
}
104+
```
105+
106+
and a constructor function with the same name
107+
108+
```
109+
fn TS(arg0: Type0, arg1: Type1, arg2: Type2) -> TS {
110+
TS{0: arg0, 1: arg1, 2: arg2}
111+
}
112+
```
113+
114+
Tuple structs have 0 or more automatically-named fields and are defined in both type (the type `TS`)
115+
and the value (the constructor function `TS`) namespaces.
116+
117+
As a basic struct, a tuple struct can participate in struct expressions `TS{0: expr, 1: expr}`,
118+
including FRU `TS{0: expr, ..ts}`/`TS{..ts}` and in struct patterns
119+
`TS{0: pat, 1: pat}`/`TS{0: pat, ..}`/`TS{..}`.
120+
In both cases the path `TS` of the expression or pattern is looked up in the type namespace.
121+
Fields of a braced tuple can be accessed with dot syntax `ts.0`.
122+
123+
As a constructor, a tuple struct can participate in tuple struct expressions `TS(expr, expr)` and
124+
tuple struct patterns `TS(pat, pat)`/`TS(..)`, both of these are looked up in the value namespace
125+
in which the constructor `TS` is defined. Tuple struct expressions `TS(expr, expr)` are usual
126+
function calls, but the compiler reserves the right to make observable improvements to them based
127+
on the additional knowledge, that `TS` is a constructor.
128+
129+
Note: the automatically assigned field names are quite interesting, they are not identifiers
130+
lexically (they are integer literals), so such fields can't be defined manually.
131+
132+
## Summary of the changes.
133+
134+
Everything related to braced structs and unit structs is already implemented.
135+
136+
New: Permit tuple structs and tuple variants with 0 fields. This restriction is artificial and can
137+
be lifted trivially. Macro writers dealing with tuple structs/variants will be happy to get rid of
138+
this one special case.
139+
140+
New: Permit using tuple structs and tuple variants in braced struct patterns and expressions not
141+
requiring naming their fields - `TS{..ts}`/`TS{}`/`TS{..}`. This doesn't require much effort to
142+
implement as well.
143+
This also means that `S{..}` patterns can be used to match structures and variants of any kind.
144+
The desire to have such "match everything" patterns is sometimes expressed given
145+
that number of fields in structures and variants can change from zero to non-zero and back during
146+
development.
147+
148+
New: Permit using tuple structs and tuple variants in braced struct patterns and expressions
149+
requiring naming their fields - `TS{0: expr}`/`TS{0: pat}`/etc. This change looks a bit worse from
150+
the cost/benefit point of view. There's not much motivation for it besides consistency and probably
151+
shortening patterns like `ItemFn(name, _, _, _, _, _)` into something like `ItemFn{0: name, ..}`.
152+
Automatic code generators (e.g. syntax extensions like `derive`) can probably benefit from the
153+
ability to generate uniform code for all structure kinds as well.
154+
The author of the RFC is ready to postpone or drop this particular extension at any moment.
155+
156+
# Drawbacks
157+
[drawbacks]: #drawbacks
158+
159+
None.
160+
161+
# Alternatives
162+
[alternatives]: #alternatives
163+
164+
None.
165+
166+
# Unresolved questions
167+
[unresolved]: #unresolved-questions
168+
169+
None.

0 commit comments

Comments
 (0)