In my opinion, a library is not necessary nor particularly beneficial. (By the way, I am one of the creators of Ramda.)
Bergi's JavaScript translation is satisfactory, although I believe it is more idiomatic, especially in browser-side JS, to encapsulate the helper function within a local closure, similar to Sibi's suggestion.
Martin Drautzburg raises a valid point about the performance issue due to the lack of widespread implementation of tail-call optimization, despite being specified. One exception is Babel's support for direct recursion, which can provide the expected performance advantage in a Babel-transpiled version.
If you are pursuing this for its elegance and have faith that TCO will be widely implemented soon, and if current potential performance issues do not concern you, then these responses offer valuable insights. Additionally, here's another ES6 technique:
// Double -> Int -> Double -> Double
function powerAcc(x, y, acc = 1) {
return y == 0 ? acc : powerAcc(x, y - 1, acc * x);
}
powerAcc(2, 5); //=> 32
Default function parameters can help replace some basic forms of pattern matching in this language, which lacks true pattern matching capabilities. While still dependent on TCO, this approach results in cleaner code and should perform well in Babel.