loop { x ← a*x }
as one functional call x(t) = exp(-k*t), so that one looks pointless. But moving-average type expressions loop { x ← a*x + f(t) }
are more interesting. You can't generally refactor those into exp() calls, like x(t) = sum[ f(t_i) * exp(-k*(t - t_i)) ], since that introduces a memory leak – you need to hold an explicit list of all the past values of f(t), in order to compute it this way. That's why the pattern [0] is uniquely useful: it's a trick to incrementally accumulate a moving average using just one variable of state.[0] https://en.wikipedia.org/wiki/Moving_average#Exponential_mov...
Here's one uncontrived way this pattern might show up: "the NPC has a numeric disposition towards the player, and the player's actions have positive and negative effects on it. These effects have finite duration, and disposition decays back to the neutral value". Another way: you have a large list (like a time series) you want to reduce to a small one by interpolation. Another way: you have some PID-like controller in your program, and to make it behave, you need a cheap filter to clean a jittery input signal. (I'm building these for my Factorio factories right now – it's the only reason this example occurred to me. "x ← (99/100) * x" is a factory control component I had to implement out of int32_t's).
For money systems, we also tend to round on every step to the nearest penny.
What you don’t have with rationals is the problem of 10.00 - 4.10 + 3.20 ending in a 9.
Rationals might not be the solve all problems type, but here they seem very applicable.