'Is it safe to use mutable let bindings inside task CEs or async CEs?
When you think you know, you don't know, is what went through my head earlier today. While going over someone's code I noticed something similar to:
task {
let mutable pleaseContinue = true
let mutable state = MyState.Running
while pleaseContine do
match x with
| Ok ->
// do something
do! runSomeTasks()
state <- MyState.Running
pleaseContinue <- true
| Error err ->
do! Log.Fatal err "Something bad"
state <- MyState.Crashed
pleaseContinue <- false
| ... // originally many other states
return
}
Basically, whenever I see mutable
in someone else's code I tend to want to get rid of it. But short of that, I found myself wondering whether the mutable variables inside task
and the like are properly part of the closure and are safe to read/update/write, as long as they aren't defined outside the task
CE builder.
Is this a correct and safe assumption?
This is in F# 6.0, and using Microsoft.FSharp.Control.TaskBuilder
and friends.
Solution 1:[1]
This looks fine to me.
See https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions.
The builder implements the body of the while loop as a recursive function. It can modify state
and pleaseContinue
since the variables are in scope.
I'm just not clear where the x
that you refer to is declared or mutated - presumably as part of the omitted code before the return
statement. In any case, if it is in scope, it should be fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Roland Andrag |