1

I'm trying to write a function that reverses a list. The function is recursive.

I know javascript does not have TCO, but i wanted to experiment with this anyway:

reverse = function(list) {
    if (list.length < 2) { return list }
    fk = fork(list);
    return reverse(fk.tail).concat([fk.head])
}

the fork function splits a list to a head and a tail:

fork = function(list) {return {head: list[0], tail: list.slice(1)}}

When I call reverse() with the list [1,2,3,4,5], I get this result:

reverse([1,2,3,4,5]) // [5,4,4,4,4]

Not sure what I'm doing wrong here. The expected result is [5,4,3,2,1].

Please help.

2
  • 1
    You know this is already built in natively as Array.reverse Commented Feb 3, 2016 at 17:37
  • I know this, but i wanted to build it myself in scholarly interest. Commented Feb 3, 2016 at 17:42

1 Answer 1

5

You should lint your code, that'll help you tremendously. In particular, this code fails because fk is treated as a global variable. If you prefix it with var, it works:

var reverse = function(list) {
    if (list.length < 2) { return list }
    var fk = fork(list);
    return reverse(fk.tail).concat([fk.head])
}

As it stands now, at each recursive call you modify the same fk variable, essentially meaning concating the same fk.head - the element before the last one.


In fact, you don't even need temporary variable here:

function recursive_reverse(list) {
  return list.length < 2 ? list : recursive_reverse(list.slice(1)).concat([list[0]]);
}

As for tail recursion, here's one possible approach:

function recursive_reverse(list) {
  return tail_recursive_reverse(list, []);
}

function tail_recursive_reverse(list, res) {
  if (!list.length) return res;
  var head = list[0];
  var tail = list.slice(1);
  res.unshift(head);
  return tail_recursive_reverse(tail, res);
}
Sign up to request clarification or add additional context in comments.

5 Comments

this line return tail_recursive_reverse(tail, (res.unshift(head), res)); calls the tail recursive function with 3 arguments instead of two. Did you mean for the last two to be in an array?
No, it's two arguments there; the second one is the result of comma expression (that is its second operand - res). Parentheses are for a reason there. )
What is the need for the comma expression?
res.unshift(head) returns a new length of an array, not an array itself. But in this case, one wants res to be passed further. Of course, it's not necessary, one can just write res.unshift(head) as a standalone expression. I've rewritten, as it seems to cause a confusion.
interesting... i didnt know one could do that. thanks for the explanation.

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.