Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with recursive javascript code?

I have the following code of a simple recursive function in javascript :

function print(text) {
    if (!text) {
        throw 'No text in input !';
    }
    console.log('print : '+text);
}

function stack(msg, stackSize) {
    stackSize++;
    print('Stack Entry '+stackSize);
    if (stackSize < 4) {
        stack(msg, stackSize);
    } else {
        print(msg);
    }
    print('Stack exit '+stackSize);
}

stack('foobar',0);

which produce the following output :

print : Stack Entry 1
print : Stack Entry 2
print : Stack Entry 3
print : Stack Entry 4
print : foobar
print : Stack exit 4
print : Stack exit 3
print : Stack exit 2
print : Stack exit 1

After banging my head on this very trivial code, i still don't get why the stack exit value is decrementing ?

like image 828
seb_kaine Avatar asked Oct 02 '15 08:10

seb_kaine


3 Answers

This is how it's executed, and it's actually obvious. When you have recursive functions, think at them like having boxes in boxes in boxes ... in boxes:

 +-------------------------+
 | 1                       |
 |   +-------------------+ |
 |   | 2                 | |
 |   | +----------------+| |
 |   | | 3              || |
 |   | | +-------------+|| |
 |   | | | 4           ||| |
 |   | | +-------------+|| |
 |   | +----------------+| |
 |   +-------------------+ |
 +-------------------------+

First it goes in, and then out:

  • stackSize: 1
    • stackSize: 2
      • stackSize: 3
        • stackSize: 4
        • stackSize: 4
      • stackSize: 3
    • stackSize: 2
  • stackSize: 1
like image 175
Ionică Bizău Avatar answered Oct 18 '22 01:10

Ionică Bizău


What is happening

stackSize is function parameter, so it is stored in the stack, when the function is returning from recursion, the value is accessed from stack, it is the same value that was passed when the function is called.

When returning from the recursive call, the topmost frame from the stack is popped out and the parameter values are read from it. Function parameters are stored on stack which are not shared between two function calls, even when the same function is called recursively.

What you were expecting

You've never declared the variable stackSize so the scope of the variable(parameter) is in the function only. If you declare the variable and don't pass it as parameter, it will be shared.

Following is what you're expecting, because the variable is shared the same value is accessed while returning from the recursive call and same value is returned.

var stackSize = 0;
function print(text) {
  if (!text) {
    throw 'No text in input !';
  }
  console.log('print : ' + text);
}

function stack(msg) {
  stackSize++;
  print('Stack Entry ' + stackSize);
  if (stackSize < 4) {
    stack(msg, stackSize);
  } else {
    print(msg);
  }
  print('Stack exit ' + stackSize);
}

stack('foobar', stackSize);
like image 40
Tushar Avatar answered Oct 18 '22 03:10

Tushar


each time you call stack you go to a deeper layer in your call stack. You could write it down like this to see the function calls you do:

stack('foobar',0);
    print('Stack Entry 1');
    stack('foobar',1);
        print('Stack Entry 2');
        stack('foobar',2);
            print('Stack Entry 3');
            stack('foobar',3);
                print('Stack Entry 4');
                stack('foobar',4);
                    print('foobar');
                print('Stack exit 4');
            print('Stack exit 3');
        print('Stack exit 2');
    print('Stack exit 1');
like image 1
Pinguin895 Avatar answered Oct 18 '22 01:10

Pinguin895