Can't understand this one

Hi, here i can’t manage to understand this type of function. If there is the function inside itself, isn’t this part return number + sum(number - 1); equivalent as return number + sum(number -1) + return number + ... indefinitely ? If you see what i mean ^^

function sum(number) { 
    
    if(number == 1) {
        return 1;
    }

    return number + sum(number - 1); 

}

console.log(sum(5));

//shows 15

This is recursion.

A rough sketch of the process being that: you call a function and pass it an argument. As the function is being executed, the function then calls itself but with a slightly different argument. The original function pauses and awaits the return value of this fresh function call. It is crucial that to avoid an infinite spiral, there must be a base case or stop condition. In the snippet you posted, this base case is:

if (number == 1) {
    return 1;
}

If we omitted this base case, we would just end up in an infinite spiral until we exceed the available memory or crash.

When you make the function call

console.log(sum(5));
  • 5 is passed as the argument to the sum function. The sum function is executed. When it reaches the return statement,
return number + sum(number - 1);
// it is evaluated as:
return 5 + sum(5 - 1);

The execution of this function’s body pauses as it awaits the result of the function call sum(4).

  • The old function call is paused and waiting. 4 is passed as the argument to a fresh call to the sum function. That function will eventually try to evaluate
return 4 + sum(4 - 1);

Now, this function will also pause and await the result of a new function call sum(3).

  • And so on …

  • … until the function call sum(2 - 1) or sum(1) is made. Now, finally the base case is met and the value 1 is returned. And then we travel up the chain until our original function call can be completed.

console.log(sum(5));

// First function call pauses when it reaches
return 5 + sum(5 - 1);
// Second function call pauses when it reaches
return 4 + sum(4 - 1);
// Third function call pauses when it reaches
return 3 + sum(3 - 1);
// Fourth function call pauses when it reaches
return 2 + sum(2 - 1);

// Fifth function call meets the base case condition
return 1;

// This propagates back up

// Fourth function can now be completed and returns a value
return 2 + sum(2 - 1);  
// becomes
return 2 + 1;

// Third function can now be completed and returns a value
return 3 + sum(3 - 1);  
// becomes
return 3 + 3;

// Second function can now be completed and returns a value
return 4 + sum(4 - 1);  
// becomes
return 4 + 6;

// First (original) function can now be completed and returns a value
return 5 + sum(5 - 1);  
// becomes
return 5 + 10;

console.log(sum(5));
// 15

Suppose you had made the function call,

console.log(sum(0));
// or 
console.log(sum(-5));

then you would crash or run out of memory as you will exceed the maximum call stack size. To avoid this, you would have to modify your base condition.

2 Likes

Ok very clear thank you :+1:
Only thing i don’t understand is the back up part. If you start from 2 this will never end because it returns only when number == 1 right ?

I don’t quite follow. Can you elaborate a bit more?
Give a sketch/reasoning of how (sum(2) ?) or some other argument will cause an infinite recursion.

The code you shared will work for all integer arguments greater than or equal to 1. In its current form, the function can’t handle 0 or negative arguments.