You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 5, 2025. It is now read-only.
While ordinary {tech}[state monads] encode stateful computations with tuples that track the contents of the state along with the computation's value, Lean's runtime system also provides mutable references that are always backed by mutable memory cells.
29
30
Mutable references have a type {lean}`IO.Ref` that indicates that a cell is mutable, and reads and writes must be explicit.
30
31
{lean}`IO.Ref` is implemented using {lean}`ST.Ref`, so the entire {ref "mutable-st-references"}[{lean}`ST.Ref` API] may also be used with {lean}`IO.Ref`.
Mutable references are often useful in contexts where arbitrary side effects are undesired.
45
56
They can give a significant speedup when Lean is unable to optimize pure operations into mutation, and some algorithms are more easily expressed using mutable references than with state monads.
46
57
Additionally, it has a property that other side effects do not have: if all of the mutable references used by a piece of code are created during its execution, and no mutable references from the code escape to other code, then the result of evaluation is deterministic.
The {lean}`ST` monad is a restricted version of {lean}`IO`in which mutable state is the only side effect, and mutable references cannot escape.{margin}[{lean}`ST` was first described by {citehere launchbury94}[].]
49
65
{lean}`ST` takes a type parameter that is never used to classify any terms.
50
66
The {lean}`runST` function, which allow escape from {lean}`ST`, requires that the {lean}`ST` action that is passed to it can instantiate this type parameter with _any_ type.
51
67
This unknown type does not exist except as a parameter to a function, which means that values whose types are “marked” by it cannot escape its scope.
@@ -155,32 +196,55 @@ Final balance is zero or positive.
155
196
156
197
{docstring ST.Ref.modifyGet}
157
198
199
+
:::comment
158
200
## Comparisons
201
+
:::
202
+
203
+
## 比較(Comparisons)
204
+
159
205
160
206
{docstring ST.Ref.ptrEq}
161
207
208
+
:::comment
162
209
## Concurrency
210
+
:::
211
+
212
+
## 並行性(Concurrency)
213
+
163
214
215
+
:::comment
164
216
Mutable references can be used as a locking mechanism.
165
217
_Taking_ the contents of the reference causes attempts to take it or to read from it to block until it is {name ST.Ref.set}`set` again.
166
218
This is a low-level feature that can be used to implement other synchronization mechanisms; it's usually better to rely on higher-level abstractions when possible.
Each thread simulates a purchase attempt: it generates a random price, and if the account balance is sufficient, it decrements it by the price.
178
238
If the balance is not sufficient, then it is not decremented.
179
239
Because each thread {name ST.Ref.take}`take`s the balance cell prior to checking it and only returns it when it is finished, the cell acts as a lock.
180
240
Unlike using {name}`ST.Ref.modify`, which atomically modifies the contents of the cell using a pure function, other {name}`IO` actions may occur in the critical section
181
241
This program's `main` function is marked {keywordOf Lean.Parser.Command.declaration}`unsafe` because {name ST.Ref.take}`take` itself is unsafe.
0 commit comments