F# - Mutable context when applying sequence transformation
Apologies for the strange title of the post, I'm not sure what the best
way to describe it is.
The general problem:
Do a sequential application of Seq.map (or similar function), except for
each item in the list, also pass in a "context". Each iteration can modify
this "context", and the updated version should be passed into the next
item in the list.
The specific problem:
I'm creating a compiler in F#. The step that I am currently on is
transforming stack-based IL to register-based IL. I was thinking I could
"walk" the stack-based IL and carry along the current "eval stack"
(similar to .NET's eval stack). Each stack IL opcode, would, obviously,
mutate the stack (example: the "add" opcode pops two items off the stack
and pushes the result). This updated stack would be passed into the next
opcode's emit cycle.
Note that I am very new to functional programming (I learned of it a week
ago), coming from a C# background, and my primary question is "what is the
'functional' way to do this?"
Here's my best guess of what a 'functional' approach to this would be
(psudocode). I dislike the tuple return value of
"transformStackToRegisterIL", is it required if I want to keep with the
standard of immutable values? Also, I'm worried about a stack overflow on
excessively long blocks of IL, is this a valid concern of mine?
let rec translate evalStack inputIl =
match inputIl with
| singleOpcode :: tail ->
let (transformed, newEvalStack) = transformStackToRegisterIL
evalStack singleOpcode
transformed :: translate newEvalStack tail
| [] -> []
Edit: Is List.scan a built-in function of what I want? (it seems similar,
but not exactly right... but it might be the correct one, I'm not sure)
No comments:
Post a Comment