After some days of analysis and complex examples of programming, based on adventofcode 2019, I have derived some useful theorems about functional programming.
There are 3 concepts we need to understand: mutability, shadowing and recursion.
F# has different forms of variables: immutable and mutable (plus byref like C# and ref like OCaml).
First theorem of shadowing
You can always represent the changes of an immutable functional-style variable with shadowing.
Second theorem of mutability
Aside from while loop (and record type fields, if you need a single instruction for multiple assignment), you can always represent the changes of a mutable imperative-style variable with shadowing.
You have 2 options to transform an imperative-style while-loop with mutable variables to a functional-style code
- tail-recursion if it is doable, but this is not always possible in F# (as opposite to haskell) without reintroducing stack explosion in some edge cases, because F# is a strict , eagerly evaluated FP while haskell is non-strict, lazy
- you can always Seq/List/Array .unfold and in this way you can represent the imperative loop as a functional state machine (see most of AoC2019 solutions on github for practical, albeit complex examples)