2 ms·
> For example, something as simple as assigning a variable has so much more meaning and functionality than I am used to, thanks to pattern matching. Once I gro
by chriswarbo 10y ago
> For example, something as simple as assigning a variable has so much more meaning and functionality than I am used to, thanks to pattern matching.
Once I grokked FP, I started thinking about this the other way around. If I see code like this in FP:
x = 5;
foo
I read this as "evaluate 'foo', substituting 'x' with '5'" (accounting for shadowing, etc.). In other words, it's sugar for "let x = 5 in foo", or "(lambda x. foo) 5".
In contrast, I read the same 2 lines in an imperative program as "first update the contents of memory location 'x' to contain '5', then evaluate 'foo'". This is much more complicated (i.e. has more meaning/function) than the FP version:
- We're specifying an evaluation order (do this, then do that), whilst the FP version works with any evaluation order. Among other things, this makes it difficult to evaluate in parallel (imagine if '5' were 'someExpensiveCalculation' and 'foo' were 'anotherExpensiveCalculationWhichMightNotUseTheFirst').
- We need a notion of "memory cells", which don't follow the lexical/syntactic nature of scoped variables; i.e. the first line may affect references in a seemingly separate piece of code. This makes reasoning much harder (although techniques like separation logic can make many common cases easier).
- The 'foo' calculation may affect the contents of 'x', so we can't trust the "equation" 'x = 5' to hold after (or even part-way-through!) the evaluation of 'foo'
One nice approach is "static single assignment"; it looks imperative (e.g. "single assignment C" looks like C), but it follows the FP semantics. In other words, it's useful when you want to show that your code is "straightforward": if you write it in C, the maintainer/compiler might guess that it's straightforward (e.g. that you don't invalidate the "x = 5") but doesn't know; in single assignment C, they know because the compiler enforces it.