Reputation: 1026
I was doing some functional programming practice with javascript lambda expressions and came up with the following code. The code aims to return a function that calculates given number's power of given base value. My code as follows;
const findUpper = base => (num, i = 0) => {
if (num < base) {
return i;
} else {
i++;
return findUpper(Math.round(num / base), i);
}
}
const findUpper2 = findUpper(2)
console.log(findUpper2(8)) //expected to have 3
The problem here is, recursion becomes broken after first findUpper
call, because it returns a function.
How can I make this snippet work?
Upvotes: 0
Views: 1105
Reputation: 135227
Here's your mistake
i++
return findUpper(Math.round(num / base), i);
You intended:
// don't forget, findUpper is a curried function
return findUpper(Math.round(num/base))(i + 1);
Here's another way to write your program as a pure expression
const findUpper = (base = 1) => (num = 0, exp = 0) =>
num < base
? exp
: findUpper (base) (num / base, exp + 1)
console.log (findUpper (2) (8))
Using generic loop
/recur
procedures, we keep findUpper
's parameters clean, increase loop performance, and maintain the curried interface you want
const recur = (...values) =>
({ recur, values })
const loop = f =>
{
let acc = f ()
while (acc && acc.recur === recur)
acc = f (...acc.values)
return acc
}
const findUpper = (base = 1) => (num = 0) =>
loop ((n = num, exp = 0) =>
n < base
? exp
: recur (n / base, exp + 1))
console.log (findUpper (2) (8))
Upvotes: 0
Reputation: 1
One way is like this
var findUpper = base => {
let fn = (num, i = 0) => {
if (num < base) {
return i;
} else {
i++;
return fn(Math.round(num / base), i);
}
};
return fn;
}
var findUpper2 = findUpper(2)
console.log(findUpper2(8))
Declare the recursive function with a name inside fundUpper ... recursively call fn rather than findUpper
it's slightly "tidier" without using arrow functions needlessly
var findUpper = base => {
return function fn(num, i = 0) {
if (num < base) {
return i;
} else {
i++;
return fn(Math.round(num / base), i);
}
};
}
var findUpper2 = findUpper(2)
console.log(findUpper2(8))
Although, using => the code can be as simple as
const findUpper = base => {
let fn = (num, i = 0) => (num < base) ? i : fn(Math.round(num / base), i + 1);
return fn;
}
Upvotes: 3