Skip to content

Commit 225c3a0

Browse files
authored
Clarify thread-safety in F# conventions article (#5422)
* Clarify thread-safety * Update conventions.md
1 parent 3e53bc9 commit 225c3a0

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

docs/fsharp/style-guide/conventions.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,19 @@ There are many times when initializing a value can have side effects, such as in
147147
module MyApi =
148148
let dep1 = File.ReadAllText "/Users/{your name}/connectionstring.txt"
149149
let dep2 = Environment.GetEnvironmentVariable "DEP_2"
150-
let dep3 = Random().Next() // Random is not thread-safe
150+
151+
let private r = Random()
152+
let dep3() = r.Next() // Problematic if multiple threads use this
151153
152154
let function1 arg = doStuffWith dep1 dep2 dep3 arg
153155
let function2 arg = doSutffWith dep1 dep2 dep3 arg
154156
```
155157

156158
This is frequently a bad idea for a few reasons:
157159

158-
First, it makes the API itself reliant on shared state. For example, multiple calling threads may be attempting to access the `dep3` value (and it is not thread-safe). Secondly, it pushes application configuration into the codebase itself. This is difficult to maintain for larger codebases.
160+
First, application configuration is pushed into the codebase with `dep1` and `dep2`. This is difficult to maintain in larger codebases.
161+
162+
Second, statically initialized data should not include values that are not thread safe if your component will itself use multiple threads. This is clearly violated by `dep3`.
159163

160164
Finally, module initialization compiles into a static constructor for the entire compilation unit. If any error occurs in let-bound value initialization in that module, it manifests as a `TypeInitializationException` that is then cached for the entire lifetime of the application. This can be difficult to diagnose. There is usually an inner exception that you can attempt to reason about, but if there is not, then there is no telling what the root cause is.
161165

0 commit comments

Comments
 (0)