Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

I've recently started wrapping the inside of my recursive functions to protect them against renaming/passing:

For instance, say you have:

let factorial = n => {
  if (n == 1) return 1;
  return n * factorial(n-1);
}

What if this happens:

let recursiveFunc = factorial;

factorial = 1;

recursiveFunc(5)  // doesn't work

recursiveFunc refers to the original function, but, because the original function calls factorial, which got redefined, it no longer works.

Even if you think this specific scenario is unlikely, passing around functions is pretty commonplace in JS-land, and, who knows, maybe the function got imported with a different name, or you received the function as a member of an object.

A solution. Do the recursion inside the function:

let factorial = n => {
  const factorial = n => {
    if (n == 1) return 1;
    return n * factorial(n-1);
  }
  return factorial(n);
}

let recursiveFunc = factorial;

factorial = 1;

recursiveFunc(5)  // works!
@sethetter

This comment has been minimized.

Copy link

@sethetter sethetter commented Apr 3, 2019

FWIW, this is often how things are done in Haskell when recursion is needed (quite often).

@Mottie

This comment has been minimized.

Copy link

@Mottie Mottie commented Apr 3, 2019

This is why you use const instead of let.

@edmangimelli

This comment has been minimized.

Copy link
Owner Author

@edmangimelli edmangimelli commented Apr 3, 2019

This is why you use const instead of let.

That solves the example, but the example isn't how I would expect it to happen in the wild.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment