And the other way around too. Even your C compiler can't reason about mutability, so it un-imperatives everything first:
int foo(int i, int j) {
while (i < 10) {
j += i;
i++;
}
return j;
}
That (j += i) line becomes: %9 = load i32, ptr %3, align 4, !dbg !23 // read i into %9
%10 = load i32, ptr %4, align 4, !dbg !25 // read j into %10
%11 = add nsw i32 %10, %9, !dbg !25 // sum %9 and %10 into %11
(i++;) becomes: %12 = load i32, ptr %3, align 4, !dbg !26 // read i into %12
%13 = add nsw i32 %12, 1, !dbg !26 // store i+1 into %13Checking on godbolt, there's definitely mutation at least sometimes. Using gcc 13.2, I get the following output.
j += i; becomes:
movl -4(%rbp), %eax // move i into %eax
addl %eax, -8(%rbp) // add i to j
With i++ becoming: addl $1, -4(%rbp). // add 1 to i
If your example is IR, do you happen to know how it crunches everything "back down" to mutability? Does it just check that the previous value of i and j were never used and use the same registers as an optimization?That said, I confess I'm curious how on what the constraints are on this one. I thought there was an increment instruction, specifically. I'm guessing safety and general debugging concerns? And it occurs to me that you are showing an intermediate language in this? Static Single-Assignment (SSA) is definitely in the vein of moving imperative to functional for easy manipulation there.
Definitely fun topics to explore here.
More on the subject: https://concerningquality.com/quality-and-paradigm/
I view it like coordinate systems. Polar versus Cartesian coordinates can clearly both do the same things. They each have domains where they have advantages.
You could argue that time based logic systems are the end goal, maybe? Still feels like throwing babies in bathwater.
Edit: for a fun example of reasoning without programming "functional" logic, look up juggling diagrams/notation. Not all logic is symbolic in the same way.
It's not that it's easier, it's that imperative code has implicit state.
And yes, you have to add and remove things to any model to really be able to reason about it. Is why engineering dynamics is harder than engineering statics. Things that change are hard. Reducing this to state being the enemy, though, I think is wrong in a lot of functional advocacy. State can be reasoned about without having to boil the ocean, as it were.