This is a highly skeletonized version of a financial algorithm. There's a lot more logic in the actual conditions and data processing represented here by "myFunc"--which isn't really intended to make sense in this version.
My question is: how do I understand why the use of firstMultiple
in this block is permissible and sensible. Why should it work?
The expression is mapped directly from the line marked A
to the line marked C3
where its value is used. But then at C1
and C2
--which are (roughly) the same level of "indentation" as C3
--here firstMultiple
is assigned--seemingly as if it were mutable-??
I guess I don't understand why C3
uses firstMultiple
while C1
can seemingly overwrite it. (The debugger, and running it, indicate that it's fine).
I'm hoping this question and example might elicit some insight into how to think about (nested) scopes. (I'm glad of course to have other comments on the design as well, but keep in mind that this code is extremely stripped of a lot of analysis.) (And I may have made the algorithm illogical in my stripping of it, but I'm trying to focus on the question of scope.)
let rec ListBuilder factor firstMultiple useFirstMultiple inputList outputList = // "A"
match inputList with
| [] -> []
| h::[] -> List.rev (inputList.Head :: outputList)
| _ ->
let nextInput = inputList.Head
let newOutputList, remInputList, firstMultiple = // "B"
match outputList with
| [] -> //first pass, capture firstMultiple now
let firstMultiple = nextInput * factor // "C1"
[nextInput], inputList.Tail, firstMultiple // "C2"
| _ ->
let lastOutput = outputList.Head
let multiple =
if useFirstMultiple then firstMultiple // "C3"
else lastOutput * factor
let newOutputList =
if (myfunc multiple nextInput: bool) then
nextInput :: outputList
else
outputList
let remInputList =
if not (myfunc multiple nextInput: bool) then
inputList.Tail
else
inputList
newOutputList, remInputList, firstMultiple
ListBuilder factor firstMultiple useFirstMultiple remInputList newOutputList