@@ -20,8 +20,12 @@ several different dimensions. For example, kinds can be used to identify which
20
20
types have values that are passed in floating point registers, or are safely
21
21
ignored by the garbage collector.
22
22
23
- The kind of a type has four components: the _ layout_ , the _ modal bounds_ , the
24
- _ with-bounds_ , and the _ non-modal bounds_ . The layout describes the shape of the
23
+ The kind of a type has four components:
24
+ * the _ layout_ ,
25
+ * the _ modal bounds_ ,
26
+ * the _ with-bounds_ ,
27
+ * and the _ non-modal bounds_ .
28
+ The layout describes the shape of the
25
29
data at runtime, and is used to support unboxed types. The modal bounds describe
26
30
how different types interact with our mode system. In particular, some types
27
31
don't have interesting interactions with some modes, so values of these types
@@ -80,7 +84,7 @@ addition, `int`s are not `float`s and they do not need to be garbage-collected
80
84
81
85
# The meaning of kinds
82
86
83
- In additional to ` value ` , OxCaml supports layouts like ` float64 ` (unboxed
87
+ In addition to ` value ` , OxCaml supports layouts like ` float64 ` (unboxed
84
88
floating point numbers that are passed in SIMD registers), ` bits64 `
85
89
and ` bits32 ` (for types represented by unboxed/untagged integers) and product
86
90
layouts like ` float64 & bits32 ` (an unboxed pair that is passed in two
@@ -94,7 +98,7 @@ meaning of the mode and details of the implementation of related features in the
94
98
OxCaml runtime. See the documentation for each mode to understand which types
95
99
cross on its axis.
96
100
97
- Formally, these are called modal _ bounds_ because the represent upper or lower
101
+ Formally, these are called modal _ bounds_ because they represent upper or lower
98
102
bounds on the appropriate modal axes. For _ future_ modal axes (like portability
99
103
and linearity), the kind records an upper bound on the mode of values of this
100
104
type. For example, ` int ` is ` mod portable ` because if you have an ` int ` that is
@@ -104,11 +108,11 @@ _expectations_. For example, `int` is `mod contended` because in a place where
104
108
an ` uncontended ` value is expected, it's still safe to use a ` contended ` int.
105
109
106
110
Why do past and future modal axes get different treatment in kinds? This is
107
- covered in the " Advanced Topics" section below, but isn't essential to
111
+ covered in the [ Advanced Topics] ( #advanced-topics ) section below, but isn't essential to
108
112
understand for day-to-day use of the system.
109
113
110
- The non-modal bounds encode several different properties; see the section
111
- " Non-modal bounds" below . They are called bounds because each non-modal axis
114
+ The non-modal bounds encode several different properties; see the
115
+ [ Non-modal bounds] ( ../non-modal ) document . They are called bounds because each non-modal axis
112
116
still supports a sub-kinding relationship, where a type of a more specific kind
113
117
can be used in place of a variable of a less specific kind.
114
118
@@ -130,16 +134,16 @@ contended`, or `value mod portable` and `value mod aliased`.
130
134
Adding bounds to a kind always makes the kind more specific, or lower. That is,
131
135
for any kind ` k ` , ` k mod <bounds> <= k ` .
132
136
133
- Along the future modal axes, a lower mode leads to a lower kind. So `value mod
134
- stateless <= value mod observing`, and bounding by the maximum mode has no
135
- effect. However, along the past modal axes, a _ higher _ mode leads to a lower
136
- kind. So ` value mod contended <= value mod sharing ` and bounding by the minimum
137
- mode has no effect. We can think of the past axes as flipped, when used in a
138
- kind. This is because ` value mod contended ` is more restrictive than `value mod
139
- sharing` (the former contains types that do not care at all about the value of
140
- the contention axis, while the latter contains types that still care about the
141
- distinction between ` contended ` and ` sharing ` / ` uncontended ` ), and so we must
142
- flip these past axes (somewhat unfortunately) .
137
+ Along the future modal axes, a _ lower _ mode leads to a lower kind. So `stateless
138
+ < observing ` leads to ` value mod stateless <= value mod observing`, and bounding
139
+ by the maximum mode has no effect. However, along the past modal axes, a
140
+ _ higher _ mode leads to a lower kind. So ` shared < contended ` leads to `value mod
141
+ contended <= value mod shared` and it's bounding by the minimum mode that has no
142
+ effect. Thus (beware), past modal axes are flipped, when used in a kind. For
143
+ instance, ` value mod contended ` is _ more restrictive _ than ` value mod shared ` .
144
+ The former only contains types that do not care about the value of the
145
+ contention axis, while the latter also contains types that care about the
146
+ distinction between ` contended ` and ` shared ` / ` uncontended ` .
143
147
144
148
If you want to get nerdy about it, each individual piece of a kind (the layout
145
149
and each possible axis of bounds) is a join semilattice, and the order we're
@@ -210,7 +214,7 @@ by types with any kind (e.g., `Sexpable`).
210
214
# With-bounds
211
215
212
216
Sometimes the kind of a type constructor depends on the kinds of the types that
213
- instantiate its parameters . For example, the type ` 'a list ` can mode cross on
217
+ are passed as arguments . For example, the type ` 'a list ` can mode cross on
214
218
the portability axis if ` 'a ` does.
215
219
216
220
We could have a ` list ` whose kind is restricted to work on types that more cross
0 commit comments