Why are there no loops in FP?
1–10 of 13 posts
Re: Why are there no loops in FP?
#2https://mitpress.mit.edu/sicp/full-text/sicp/book/node15.htm...
The advantage of using recursive definitions for loops is that it avoids modifying places in favor of returning values. Rich Hickey gives a good talk on the subject in The Value of Values:
Re: Why are there no loops in FP?
#3So you kinda just don't need for loops anymore and they're inherently imperative because you need to setup some sort of condition to say keep performing this sequence of actions (which is the main idea behind imperative programming) until this condition is no longer satisfied.
Re: Why are there no loops in FP?
#4For loops dont return a value, whereas forM and even forM_ both return values. They are normal functions rather than just control structures.
Re: Why are there no loops in FP?
#5Re: Why are there no loops in FP?
#6Let's start with a simple function that counts down from five in Javascript:
var countDownFromFive = function() {
console.log(5);
console.log(4);
console.log(3);
console.log(2);
console.log(1);
console.log(0);
}
So, that's the purely imperative way of doing things. We notice a pattern, though: the numbers are just a list from [5,4,3,2,1,0]. So, we could just describe them as the series S(n) = n + S(n-1), where n >= 0. So, we write it in that form: var countDownFrom = function(num) {
console.log( num );
if (num >= 0) {
countDownFrom(num - 1);
}
}
And then our count down from five becomes: var countDownFromFive = function() {
countDownFrom(5);
}
So, that's great, and that's a nice recursive definition of the problem. The problem is, though, that for a really big number, say 2^32, we've got to store a stack of results, and that blows everything up. We can fix this with tail call optimization, because we know we can reuse the same stack frames, but that's an optimization many low-level languages don't have.Indeed, until we've invented them, we don't even have the necessary concepts of a stack with function frames. So, let's look at our problem again.
Let's pretend we're in a very limited assembly language, with just registers:
LOAD registerA 5
PRINT registerA
LOAD registerA 4
PRINT registerA
LOAD registerA 3
PRINT registerA
LOAD registerA 2
PRINT registerA
LOAD registerA 1
PRINT registerA
LOAD registerA 0
PRINT registerA
So, that mirrors our pure imperative case. Aha, but let's say we're smarter than that, and we have a branch instruction and a decrement operator: start:
LOAD registerA 5
doPrint:
PRINT registerA
DECREMENT registerA
JUMP_IF_NOT_NEGATIVE registerA doPrint
finish:
HALT
So, even without the notion of a function stack, we can still print a list of numbers. We are now experts at counting down from five.~
The thing we see, though, is that the difference in implementation comes from basically whether or not you can compose functions: if you can, you use the functional approach. If you can't, you refactor the problem to have an explicit accumulator (your loop variable).
Loops can be considered an inherently imperative idea because you have this changing context wrapping the function being invoked (a mutating accumulator, if you will)--in the functional world, you merely wrap another function which itself creates a new context with the desired mutation, and that function in turn calls another function setting up its own context and so on and so forth. It's somewhat handier to prove correctness and behavior of these recursive functions compared with their mutating accumulator imperative solutions; at the same time, they are slower without compiler support.
Re: Why are there no loops in FP?
#7Re: Why are there no loops in FP?
#8Also, if you can post some code examples where you "feel you are missing something" I (or others) might be able to provide the functional examples.
At least, what makes one language imperative vs functional?
I always thought functional languages were about describing what things should do whereas imperative languages were about telling the computer what to do. I suppose in that sense loops are not really functional because they are not very descriptive, but I was wondering if there was more to it than that.
Re: Why are there no loops in FP?
#9Would you expect to see a for loop in a mathematical equation? You're correct in noticing that a lot of the reasons why you'd use a for loop are taken care of with basic functions such as map (to perform some action on different elements in a list), reduce (to do some sort of aggregation). So you kinda just don't need for loops anymore and they're inherently imperative because you need to setup some sort of condition…
Re: Why are there no loops in FP?
#10So, it's not like loops are an inherently imperative idea, so much as that they typically are something that only make obvious sense in an imperative world. Let's start with a simple function that counts down from five in Javascript: var countDownFromFive = function() { console.log(5); console.log(4); console.log(3); console.log(2); console.log(1); console.log(0); } So, that's the purely imperative way of doing thing…
I guess I never thought about it that way but the logic in the loops could be considered their own functions, except they actually can reference and alter variables outside the loop which is kind of against the ideas of functional programming.
Awesome! Thanks again