Tail function in javascript [duplicate] - javascript

This question already has answers here:
Variadic curried sum function
(19 answers)
Closed 7 years ago.
I want to make a function which adds arguments. Invoking this function should be
functionAdd(2)(3)(4)...(n);
And the result 2+3+4...+n
I'm trying this
function myfunction(num){
var summ =+ num;
if(num !== undefined){
return myfunction(summ);
}
};
But it doesn't works, an error of ovwerflow. And I don't understand where I should out from this function;

You can use the .valueOf to do the trick:
function myfunction(sum){
var accum = function(val) {
sum += val;
return accum;
};
accum.valueOf = function() {
return sum;
};
return accum(0);
};
var total = myfunction(1)(2)(3)(4);
console.log(total); // 10
JSFiddle: http://jsfiddle.net/vdkwhxrL/
How it works:
on every iteration you return a reference to the accumulator function. But when you request for the result - the .valueOf() is invoked, that returns a scalar value instead.
Note that the result is still a function. Most importantly that means it is not copied on assignment:
var copy = total
var trueCopy = +total // explicit conversion to number
console.log(copy) // 10 ; so far so good
console.log(typeof copy) // function
console.log(trueCopy) // 10
console.log(typeof trueCopy) // number
console.log(total(5)) // 15
console.log(copy) // 15 too!
console.log(trueCopy) // 10

If last call can be without arguments:
function add(value) {
var sum = value;
return function add(value) {
if(typeof value === 'number') {
sum += value
return add
} else {
return sum
}
}
}
console.log(add(1)(2)(3)(0)()) // 6

Related

How to make an ADD function that curries to the nth integer [duplicate]

This question already has answers here:
Variadic curried sum function
(19 answers)
Closed 3 years ago.
How can I realize the below?
console.log(Sum(1)) // 1
console.log(Sum(1)(2)) // 3
console.log(Sum(1)(2)(3)) // 6
console.log(Sum(1)(2)(3)(4)) // 10
I've tried,
var add = function(x) {
return function(y) { return x + y; };
}
But that's only good for one dive.
Basically you need to return a function with a toString method for getting a value, if not called as function.
function sum(x) {
function _(y) { x += y; return _; };
_.toString = function () { return x; };
return _;
}
console.log(sum(1)) // 1
console.log(sum(1)(2)) // 3
console.log(sum(1)(2)(3)) // 6
console.log(sum(1)(2)(3)(4)) // 10

Only allowing a function to run n times with wrapper function

I need to make a wrapper function to invoke a function multiply with a given number num of times to allow the multiply to execute. nTimes(num,2) Then assign to runTwice -- runTwice can be any function that invoke the nTimes function which given a different num input--
In my case, for simplicity, I am only allowing it to run 2 times num=2
If we run the runTwice function the first time and the second time it will return the result of multiply function calculated with the inputs for multiply. Any invocation after the second time will not run the multiply function but will return the latest result of the multiply function.
Here is my implementation using an object to keep track of how many times we have execute the function, the max number allowed to execute and the latest result of multiply
'use strict'
//use a counter object to keep track of counts, max number allowed to run and latest result rendered
let counter = {
count:0,
max: 0,
lastResult: 0
};
let multiply = function(a,b){
if(this.count<this.max){
this.count++;
this.lastResult = a*b;
return a*b;
}else{
return this.lastResult;
}
}
// bind the multiply function to the counter object
multiply = multiply.bind(counter);
let nTimes=function(num,fn){
this.max = num;
return fn;
};
// here the nTimes is only executed ONE time, we will also bind it with the counter object
let runTwice = nTimes.call(counter,3,multiply);
console.log(runTwice(1,3)); // 3
console.log(runTwice(2,3)); // 6
console.log(runTwice(3,3)); // 6
console.log(runTwice(4,3)); // 6
Note that I have altered the simple multiply quite a bit and bind it the counterobject to make it work. Also using call on nTimes to bind counter object.
What can I do to implement the same result with a wrapper function but less alteration to the simple multiply function?
Let's say the multiply function is very simple:
let multiply = function(a,b){ return a*b };
You could use a closure over the count and the last value and check count and decrement and store the last result.
const
multiply = (a, b) => a * b,
maxCall = (fn, max, last) => (...args) => max && max-- ? last = fn(...args) : last,
mult3times = maxCall(multiply, 3);
console.log(mult3times(2, 3));
console.log(mult3times(3, 4));
console.log(mult3times(4, 5));
console.log(mult3times(5, 6));
console.log(mult3times(6, 7));
Nina's answer is great. Here's an alternative, with code that might look slightly easier to read:
function multiply(a, b) {
return a * b;
}
function executeMaxTimes(max, fn) {
let counter = 0, lastResult;
return (...args) => counter++ < max
? lastResult = fn(...args)
: lastResult;
}
const multiplyMaxTwice = executeMaxTimes(2, multiply);
console.log(multiplyMaxTwice(1, 3)); // 3
console.log(multiplyMaxTwice(2, 3)); // 6
console.log(multiplyMaxTwice(3, 3)); // 6
console.log(multiplyMaxTwice(4, 3)); // 6
Seeing how both Nina and Jeto have answered your question, here is a simple and similar way to do it that also keeps a history of all the results in case you want to get them at a later time.
function multiply(a, b) {
return a * b;
}
function runMaxNTimes(num, callBack) {
var results = new Array(num);
var callTimes = 0;
return function(...params) {
return results.length > callTimes ?
results[callTimes++] = callBack(...params) :
results[callTimes - 1];
};
}
var runTwice = runMaxNTimes(2, multiply);
console.log(runTwice(1, 3)); // 3
console.log(runTwice(2, 3)); // 6
console.log(runTwice(3, 3)); // 6
console.log(runTwice(4, 3)); // 6

Sum function currying

I'm trying to write a sum function that does the following:
sum(1)(2)(3) => returns 6
However, I am having hard time with my solution. I know i'm making a silly mistake, can someone point me in the right direction?
My Implementation:
function add(args) {
let sum = args[0];
let func = function(...args2) {
if (!args2[0]) return sum;
sum += args2[0];
return func;
}
return func;
}
add(1)(2)(3);
Additionally, can I write a generic function that does the following?
add(1)(2)(3) or add (1)(2)(3) () => 6
To have an arbitrary amount of calls, all which take a number, you'd need the return value to behave both as a function and a number depending. So that:
const five = add(2)(3);
console.log(five(10)); // behaves like a function
console.log(five + 10); // behaves like a number
I can't think of anyway to do that (or if there's a good reason one should do that) other than what I'd call a hack.
With that said, for fun I was able to do the following by abusing valueOf():
const add = (num1) => {
const func = (num2) => add(num1 + num2);
func.valueOf = () => num1;
return func;
}
console.log(add(1)(2)(3)); // *logs function* [output varies by environment]
console.log(add(1)(2)(3) + 10); // 16
console.log(add(1)(2) + 10); // 13
console.log(add(1) + 10); // 11
console.log(add(1)(2)(3) == 6); // true
console.log(add(1)(2)(3) === 6); // false
console.log(typeof add(1)(2)(3)); // function
console.log(typeof (add(1)(2) + 3)); // number
But that's obviously not very kosher.
Edit: Switched from using toString() to valueOf() per #PatrickRoberts's comment.
Recursion anyone? 😂
function add(n) {
return function(m) {
if (isNaN(m)) return n;
return add(n + m);
};
}
// add(1)(2)(3)() => 6
// add(1)(2)(3)("")() => "6"
// add(1)("2")(3)() => "123"
// functional one liner
const add = n => m => isNaN(m) ? n : add(n + m);
Try this, you omitted the spread operator
function add(...args) {
let sum = args[0];
let func = function(...args2) {
if(args2[0] === undefined) return sum;
sum += args2[0];
return func;
}
return func;
}
console.log(add(1)(2)(3)());
cheers!!
function sum(x){
return function (y){
return function(z){
return x+y+z;
}
}
}
You can call like :
sum(1)(2)(3)

Math.max.apply(null, arr); [duplicate]

This question already has answers here:
How does the Math.max.apply() work?
(5 answers)
Closed 5 years ago.
How does
Math.max.apply(null, arr);
exactly work?
Suppose
var arr = [45,25,4,65] ;
will it compare 'null' and '45' and return maximum number between two adjacent e.g. 45?
After comparing will it again compare returned number and next array number e.g. 25 and return the max number?
And how is the calculation done internally? It is the same way, I think.
The first argument of apply is what will be this for the function.
Here it does not matter as this function does not necessit a specific this value. It could matter in some other cases for instance:
var foo = {
b: true,
func: function() {
return this.b;
}
};
var bar = { b : false };
foo.func(); // true
foo.func.apply(bar); // false
It's equal to
Math.max(...arr);
and that's equal to:
Math.max(45, 25, 4, 65);
How it works internally is then up to the browsers / parsers native implementation. In js it might be:
Math.max = (...args) => {
let max = - Infinity;
for(const number of args)
if(number > max) max = number;
return max;
};

Can I add numbers using JavaScript Closures?

How can I create a closure function, that sums all passed arguments, like this?
Add(2)(2) //4
Add(2)(2)(3) // 7
Add(3)(2)(3)(0) // 8
function Add(number){
return function(number1){
return function(number2){
return number+number1+number2;
}
}
}
alert(Add(2)(2)(2));
I wanted a generalized way to achieve this.
There are duplicates here, probably with better examples, but I can't find one right now. You need to create a closure to keep track of the sum, then return the add function. Give it valueOf and toString methods so it works in other operations:
var add = (function() {
var sum = 0;
function add(n) {
sum += +n || 0;
return add;
}
add.valueOf = function(){
return sum;
}
add.toString = valueOf;
return add;
}());
document.write(add(1)(2)(3)(-2)); // 4
document.write('<br>' + add(2)(1) * 2); // 14
document.write('<br>' + add( -add())); // 0

Categories