0

Evening, novice here, i've been trying to use tail recursion using the Function object but when i call the function again in it's body and evaluate it, it returns an error signaling that it hasn't been defined. I want to know if it's posssible to use the Function object recursively because i want to makek a function with it that takes any amount of argument, and the only way i can think of to solve it, is using recursion


var sum = new Function('...args', 
'if(args.length==2) return args[0] + args[1]; else return args[0] + sum(...args.slice[1]);');

/*
-console.log(sum(1, 2));
->returns: 3
-console.log(sum(1, 2, 3));
->returns:  Error: sum is not defined
*/

I made the same function the regular way and it worked like i expected:

function sum2(...args){
    if(args.length==2) return args[0] + args[1];
    else return args[0] + sum2(...args.slice(1));
}

/*
-console.log(sum2(1, 2));
->returns: 3
-console.log(sum2(1, 2, 3));
->returns: 6
*/


4
  • When using Function, you get the code in global scope, so sum is likely not there. Also, this seems like an XY problem - why do you need a dynamically evaluated function body with tail recursion? Commented Aug 22, 2019 at 5:44
  • Possible duplicate of new Function scope Commented Aug 22, 2019 at 5:50
  • Also relevant: stackoverflow.com/questions/28592127/… Commented Aug 22, 2019 at 5:50
  • @VLAZ im trying to use it because im solving some exercises of a book where the author is making a language and he defined some fuctions using the Function object, but in a way that it only accepts a finite amount of arguments (2), i want to modify some of those functions so that it accepts any amount of arguments, here is the way the author of the book defines those functions (and the entire language is there as well if you want to look at it and get a sense of why im doing it this way): eloquentjavascript.net/12_language.html#c_OTgmEw/s8v Commented Aug 22, 2019 at 5:53

1 Answer 1

1

To quote MDN:

Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was created. This is different from using eval with code for a function expression.

So, this does not work because var sum is not in the global scope. Here is an example:

/* global scope */
var dummyRecursion = new Function('stop', 
  `console.log("invoke with", stop);
   if(!stop) dummyRecursion(true)`);

dummyRecursion(false);

/* functional scope */
function main() {
  var dummyRecursion = new Function('stop', 
  `console.log("invoke with", stop);
   if(!stop) dummyRecursion(true)`);

  dummyRecursion(false);
}

main();

If you really need to use the new Function construct to dynamically generate functions and want to use tail recursion, then you can create an inner function and invoke it - that way you will always have visibility to it:

/* global scope */
var dummyRecursion = new Function('stop', 
  `var innerFn = function(stop) { 
    console.log("invoke with", stop);
    if(!stop) innerFn(true)
   }
   
   innerFn(stop);`);

dummyRecursion(false);

/* functional scope */
function main() {
  var dummyRecursion = new Function('stop',
    `var innerFn = function(stop) { 
      console.log("invoke with", stop);
      if(!stop) innerFn(true)
     }
   
   innerFn(stop);`);

  dummyRecursion(false);
}

main();

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.