-2

Assuming:

var x = { 
  y: function(n){ 
    console.log(n);
    console.log(n+":"+( n > 0 ? arguments.callee(n-1) + "o" : "all" ));
  } 
}; 
x.y(4)

Console log:

4 
3 
2 
1 
0 
0 -> all
1 -> o
2 -> o
3 -> o
4 -> o

The first part of the console.log makes sense to me, we're starting with n=4 , and calling the function itself with n-1, ends up 4,3,2,1,0.

However, the output of

console.log(n+":"+( n > 0 ? arguments.callee(n-1) + "o" : "all" ));

is a bit irritating since it returns the result in a 'reversed' order. Why is the value of n as first part of that execution, without arguments.callee in it giving a different result than calling it from within a ternary operator with arguments.callee? Is this a matter of pure definition or is there another logic reason for this?

The process would be as the following:
(n=4) = ( 4 > 0 ? arguments.callee(3) + "o" : "all" ) = "o"
  (n=3) = ( 3 > 0 ? arguments.callee(2) + "o" : "all" ) = "o"
    (n=2) = ( 2 > 0 ? arguments.callee(1) + "o" : "all" ) = "o"
      (n=1) = ( 1 > 0 ? arguments.callee(1) + "o" : "all" ) = "o"
        (n=0) = ( 0 > 0 ? arguments.callee(1) + "o" : "all" ) = "all"

Doesn't this have to end up in ooooall instead of alloooo?

Cheers

F4b
  • 95
  • 7
  • 1
    Huh? *"Why is the value of n as first part of that execution..."* Because...that's what the code does. What's the real question here? Note the `console.log(n)` prior to the other `console.log`. – T.J. Crowder May 19 '15 at 21:41
  • The ?'s are meant to express a question each. Thank you. – F4b May 19 '15 at 22:37
  • This post additionally helped on solving the problem: [Tail Recursion][1] [1]: http://stackoverflow.com/questions/33923/what-is-tail-recursion – F4b May 24 '15 at 22:49

2 Answers2

0

When you make the recursive call in the middle of the expression, that call has to execute to completion. What happens in the recursive call? Another iteration of that console.log(), that's what. Therefore, before the first (corresponding to 4) call can complete, the calls for 3, 2, 1, and 0 have to complete first.

Also, there's no reason to use arguments.callee. Just give your anonymous function an internal name:

var x = { 
  y: function y(n){ 
    console.log(n);
    console.log(n+":"+( n > 0 ? y(n-1) + "o" : "all" ));
  } 
}; 

Assuming you're not a time traveler from 2008, that y name is only bound inside the function.

Pointy
  • 405,095
  • 59
  • 585
  • 614
0

No, because is a recursive function so, when last function end ("all") then all previous console.log will print in reverse order (really is not reverse order, it's the correct order because is a recursive function), for example, we have the 5 steps that you say: (n=4, n=3 ... n=0):

f4 -> f3 -> f2 -> f1 -> f0

we saw that f4 calls f3, f3 calls f2 ..... and f1 calls f0. Well, when f0 finish, did the console.log with output "0" and "all", then, this function (f0) return to previous function (f1) that prints the letter "o", then f1 return to f2 ...... and the same way until return to the first function f4.

It's difficult to explain but easy to understand. I hope that my "explanation" could be enough.

Jose Mato
  • 2,709
  • 1
  • 17
  • 18