1

I really did overflow the stack on my first try, but then I put the return statement (see comment in code) without an argument and it worked.

Task:

Write a higher-order function loop that provides something like a for loop statement. It takes a value, a test function, an update function, and a body function. Each iteration, it first runs the test function on the current loop value, and stops if that returns false. Then it calls the body function, giving it the current value. And finally, it calls the update function to create a new value, and starts from the beginning.

When defining the function, you can use a regular loop to do the actual looping.

I didn't use loop.

Book Solution

function loop(start, test, update, body) {
   for (let value = start; test(value); value = update(value)) {
     body(value);
   }
 }

 loop(3, n => n > 0, n => n - 1, console.log);
 // → 3
 // → 2
 // → 1

My Solution (kept my original function parameter names)

function loop(value, test, update, execute){
  if (test(value)) execute(value);
  else return // prevents stack overflow?
  return loop(update(value),test,update,execute)


}
loop(3, n => n > 0, n => n - 1, console.log);
// → 3
// → 2
// → 1

Did I just made the console output the same thing, or will my solution do the same thing in a real-environment program?

I ask, because I'm not sure if I actually solved it with recursion, or just made the console output the same thing. This will help me feel better about myself, since I'm a noob JS learner. Thanks! :)

2
  • 1
    I don't understand what you mean by "made the console output the same thing". Commented Mar 14, 2018 at 0:24
  • In other words - Is my solution a real solution, or just luck - as you have mentioned in your other comment. Thanks man, appreciate it! Commented Mar 14, 2018 at 0:45

2 Answers 2

3

Yes, that's the correct recursive implementation for the task. You didn't just hit the correct output by chance.

The else return is a bit odd though. I would have written either

function loop(value, test, update, execute) {
  if (test(value)) {
    execute(value);
    return loop(update(value), test, update, execute);
  } // else stop
}

or

function loop(value, test, update, execute) {
  if (!test(value)) return; // stop
  execute(value);
  return loop(update(value), test, update, execute);
}
Sign up to request clarification or add additional context in comments.

Comments

2

Initializer

The book solution creates a value variable and initializes it with start. In your case this happens automatically when you pass your first parameter. So far the two approaches are equivalent.

Test

The for loop calls test(value) as cycle test. Your approach does something similar, but calling test is the test for recursion. So far the two approaches are equivalent.

Cycle block

The for loop calls body(value). Your approach calls execute(value). So far the two approaches are equivalent.

The update

value is updated in the cycle after each iteration. The same happens in your code when you pass update(value) in your recursive call. So far the two approaches are equivalent.

Are they really equivalent?

Algorithmically, yes. Technically, no. Your recursive approach calls the function several times and uses the stack (of the memory) to store the function calls. In the case of a too large numbers of test, your code will crash. So, you have successfully implemented a recursive version of the book example (yay!) but you should try to avoid recursion in most cases.

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.