3

I have a recursive function written in Javascript, which is giving RangeError because of excessive deep recursion. Hence, I have used trampolining to make it tail-optimized. This has wrapped the function call in a while loop and I have gotten rid of RangeError. But I need to handle thrown exception inside the recursive function (go back one level and do some corrective processing). I am not sure how to handle this kind of situation, while using trampolining.

My original recursive function (simplified for illustration):

function process (val, level){
   if(val < 0 ){
     throw new negativeException(val);
   }
   for(var i=0; i< num; i++){
       try{
         //do some processing on val
         process (val, level+1);
         return;
       }
       catch(e){
         //do some different processing on val and use i as well
       }
    } 
 }

function process (val, level)

My updated recursive function using trampolining (ref: Understanding recursion in functional JavaScript programming)

function trampoline(f) {
  try{
    while (f && f instanceof Function) {
        f = f();
    }
   } catch(e) {
     //catching exception in trampoline
   }
   return f;
}

function callProcess(val, level){
   function process(val, level){
     if(val < 0 ){
       throw new negativeException(val);
     }
     for(var i=0; i< num; i++){ 
        try{
          //do some processing on val
          return process.bind(null, val, level+1); /updated recursive call
        }
        catch(e){
         //do some different processing on val and use i as well
        }
     }
 }
 return trampoline(process.bind(null, pstate,level));
}

function callProcess(val, level)

With the updated code, I am able to avoid RangeError as long as val is not negative and no exception is being thrown. But when val goes negative and exception is thrown, I am directly going to the trampoline catch block. But I need to go back to the catch block of process() one level up.

Can you suggestion how I can achieve that? Thanks for your help! I have checked out some related posts, but unable to figure out the solution I need.

kajarigd
  • 1,299
  • 3
  • 28
  • 46
  • If you want to test whether an object is callable, use `typeof f === 'function'`, not `f instanceof Function`. Otherwise you may get false positives (`Object.create(Function.prototype)`) or false negatives (`document.createElement('object')`) – Oriol Jan 31 '16 at 01:17
  • The while condition is working fine for me. But I am unable to go to the catch block of process() function when an exception is thrown. – kajarigd Jan 31 '16 at 01:19
  • I don't understand the loop and its `try...catch`. Binding a function shouldn't produce any error, and then you will always return and exit the loop at the first iteration. What are you trying to achieve there? – Oriol Jan 31 '16 at 01:26
  • I am not getting any error at all. I am doing this in nodejs. When I am throwing an exception, the exception is getting caught at the trampoline() catch. I get this is happening because of the binding. But I need to enter the catch block of process() and not directly jump to trampoline() catch, I need to understand what code changes I need to do to make this happen. – kajarigd Jan 31 '16 at 01:29
  • I meant: Why do you wrap some code that won't throw inside a `try...catch`? Why do you have a loop if you will return at its first iteration? – Oriol Jan 31 '16 at 01:31
  • OK. I understand your question now. As per the program logic, I won't be returning at the first iteration. val can get negative very rarely and that too after many levels of recursive call deeper. Hence, when the exception will be thrown the program pointer will be at some deep level of recursion call. – kajarigd Jan 31 '16 at 01:34

0 Answers0