Passing arguments to a function within a function - javascript - javascript

I am trying to pass an argument to a function within a function;
function add() {
let x = arguments[0];
function s(num) {
return num + x;
}
}
add(2)(3) //second argument to be passed to 'function s'.
so im wanting the call to return 5.
What is the best approach to this? thanks in advance.

Currying is the name of the construction that allows you to partially apply the arguments of a function. It means that instead of passing multiple arguments to a function and expect a final result, you can pass a subset of this arguments and get back a function that is waiting for the rest of the arugments.
As already pointed by #KevBot, your example is missing the return of the second function and would be:
function add() {
let x = arguments[0];
return function s(num) {
return num + x;
}
}
add(2)(3);
ES6 Curryed Hello World:
curryedHelloWorld = (greeting) => (name) => `${greeting}, ${name}!`;
curryedHelloWorld("Hello")("Tygar");
You can even uncurry the curryedHelloWorld example making it the opposite way:
helloworld = (greeting, name) => curryedHelloWorld(greeting)(name);
helloworld("Hello", "Tygar");

Related

javascript: Callback function code considered as string

Am a newbie in javascript, please help me understand below case where the callback function code is being considered as a string and passed as argument instead of passing the value of the callback function as an argument:
//Case3: Create Callback function in the argument section of calling statement.
function child3(callback,arg2=3) {
return console.log("Case3: callback function - parent function out:", callback+arg2,"\n");
}
child3(parent3=()=>{
let a=1;
let b=1;
return a+b;
},2);
Output:
Case3: callback function - parent function out: ()=>{
let a=1;
let b=1;
return a+b;
}2
When you use +, there are two possibilities:
If both operands are numbers or BigInts, they are added together
Otherwise, both operands are concatenated together into a string
If you do
callback+arg2
and callback isn't a number, the result will be a concatenation of it and arg2. In your code, callback is not a number; it's a function. You probably wanted to call the callback instead of concatenating it - eg, callback().
Another issue is that
child3(parent3=()=>{
should almost certainly be
child3(()=>{
unless you deliberately wanted to both create a new global function named parent3 and pass that to child3.
function child3(callback, arg2 = 3) {
console.log(callback() + arg2);
}
child3(() => {
let a = 1;
let b = 1;
return a + b;
}, 2);
It's not a string, but a parameter. It has a name in the function's parameter list, which is callback, so, inside the function it is referred to as callback and when you pass
"Case3: callback function - parent function out:", callback+arg2,"\n"
to console.log, you convert the function to string. By the way, you can do that without passing the function as parameter as well
function foo(a, b) {
return a + b;
}
console.log(foo);
So, you do not pass it as a string, you pass it as a function instead, but it is converted into a string, i.e. the function definition when you call console.log.

javascript flexible argument for curry function

I have a question regarding curry function..
I know that if I have this simple curry function:
const greeting = (greet) => {
return (name) => {
return `${greet} ${name}`;
};
};
I can call greeting('Hello')('John') and it will return Hello John.
Is there a way to make it flexible say between 1 parameter and 2 parameters, ex: with
the above greeting function, is there a way for me to call greeting('Hello') and greeting('Hello')('John') and it will return Hello and Hello John respectively?
I know that I can do it with greeting('Hello')() and greeting('Hello')('John') but I was just trying to avoid breaking changes because I already have a greeting method and want to extend it using curry function, so I want it to also accept greeting('Hello') without the extra () at the end...
thanks
I can think of only one option that works by coercing the curried function into a string. This won't change the return value but it will allow you to get the result you want depending on context.
const greeting = greet => Object.defineProperties(
name => `${greet} ${name}`, // curried
{
toString: {
value: () => greet,
},
valueOf: {
value: () => greet
}
}
)
console.log(typeof greeting("Hello")) // function, not string
console.log(`${greeting("Hello")}`) // note the string context
console.log(`${greeting("Hello")("World")}`)
If you need the return value to actually toggle between a function and a string however, the answer is no.
In order for greeting("Hello")("John") to return a string, greeting("Hello") must return a function.
There is no way to tell within greeting() how the curried function is going to be called so you cannot detect whether or not to return a function or a string.
Think of it this way, greeting("Hello")("John") is just a short version of...
const fn = greeting("Hello")
// later or maybe never...
fn("John")
You simply don't know how, when or even if that curried function will be called.
Is there a way? Sure. But why? because won't that be "un-currying" it? And you will have to modify the function of-course.
You can always do something like this just get the output your asked for:
const greeting = (greet) => {
const split = greet.split(" ");
if(split.length > 1)
return `${split[0]} ${split[1]}`;
else return (name) => {
return `${greet} ${name}`;
};
};
If you use a helper function for currying, you can get a similar behavior automatically. For example, take the implementation at javascript.info/currying-partials
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
You can define
const greeting = curry((greet, name) => `${greet} ${name}`)
and call
greeting("Hello", "John")
or
greeting("Hello")("John")

What are the parameters in arow function in JS?

please help the newbie figure it out.
There is such a code:
function makeDouble (x) {
return x * 2;
}
var doMath = (x, func) => func(x + 5);
var num = 5;
The task is:
*Using only makeDouble, doMath, and num, make the value of num equal to 20.
num = _____________________________________________________*
I can’t understand why there are two parameters in the parameters of an arrow function, but in the body of this function itself there is only one parameter. What am I doing wrong?
You can translate the arrow function as:
function doMath(x, func) { return func(x+5); }
So you pass a value (x) and a function (func) to the doMath function. func can be any function, for example makeDouble... You can call it like:
doMath(1, makeDouble)
And the result will be (1+5)*2 = 12.
I think you can figure out the rest based on this.
Both parameters in doMath() are being used. The first is argument x will be applied as an argument in the function call of the second argument func and the value returned from that function call will be returned by doMath() itself.
The answer is
num = doMath(num, makeDouble)
There are also 2 parameters in the body of the function.
Let's look a little bit closer
func(x+5)
func is a second parameter of the function and x that we pass to it is a first parameter
Here, func is a callback function. In javascript, you can pass a function as a parameter just like you pass any other variable, for e.g, an integer, object or an array. So here in doMatch you're passing a number and a callback function. When doMatch executes, it calls func with the parameter 10 (5+5). Func, now, will be executed and will return 2*10 (20)
function makeDouble (x) {
return x * 2;
}
var doMath = (x, func) => func(x + 5);
var num = 5;
console.log(doMath(num, makeDouble))
function makeDouble (x) {
return x * 2;
}
const doMath = (x, func) => func(x + 5);
const num = 5;
let result = doMath(num, makeDouble);
console.log(result);// 20
doMath(x, func) is an arrow function which takes two parameters. The first para meters is your numeric value, and the second is a function which in this case is makeDouble(x). Inside the arrow function, the makeDouble(x) function is called with the numeric parameter + 5 like makeDouble( num + 5). In this case, num is added five inside the constructor, so this time makeDouble returns the product of 10 * 2. Also, I would suggest to revise the use of var. Currently the use of let and const is preferred over var.
Arrow functions can take other functions as parameters, which is great to work with recursion and functional programming.
Thank very much you all!
My problem was that I did not notice that the makeDouble() function in the parameters of the arrow function did not return the value, but the content of the function itself. And then in the body of the arrow function, it can be to call the makeDouble() function as a parameter.

How can I access the result from a previous function in a currying function?

I have to write a currying function that takes a function, executes another function, then executes a second function by taking the last argument as the value to calculate with.
What I am struggling with: How can I access the first function and the value at the end at the same time?
So far I can access the first function by writing a function in the function syntax and accessing the this.
Function.prototype.foo = function(x) {
// can't make currying functions by using functions keyword
console.log(this, x);
};
(() => 10).foo(1);
When I write a currying function I can access the second (x) and third (y) function.
Function.prototype.bar = x => y => {
// but also can't access this like in function syntax
console.log(x, y);
}
// how would I access 10 in bar?
(() => 10).bar(1)(2);
The final Function would look something like that:
someFunc.then(someSecondFunc).then(someThirdFunc)(100)
Thank you so much for your help!
Not sure if it solves your problem, but you can make currying functions with the function keyword:
Function.prototype.bar = function(x) {
return function(y) {
console.log(x, y)
}
}
I wasn’t able to actually able to validate if this works:
(function() {return 10}).bar(1)(2)
In any case, ˋthisˋ would be the function, not the return value (10), since the function is not called.
By using currying functions and the function keyword, my answer looks like this:
Function.prototype.then = function(secondFct) {
const firstFct = this;
return function(value) {
return firstFct(secondFct(value));
}
}
Many thanks to buboh for the help.

Currying - How is returned function called with a second argument in JavaScript?

How does the second argument get called in liftf(add)(1)?
function add (first, second) {
return first + second;
}
function liftf (binary) {
return function (first) {
return function (second) {
return binary(first, second);
};
};
}
var inc = liftf(add)(1);
I understand how lift(add) is called and stored.
I am confused on how a function is returned but then called with (1).
I first explored if it operated on the same principle of an IIFE but it doesn't seem to. IFFE's would be (function() {}()) vs funciton() {}().
The 'chained' function arguments confuse me and I want to understand what's going on.
Thanks!
If an expression evaluates to a function, then that function can be invoked with parentheses and the list of arguments.
Since the expression liftf(add) returns a function, you call the returned function with the parameter 1 in parentheses: liftf(add)(1)
Another way to look at it is if you set liftf(add) to a variable, then you could call the function stored in that variable:
var additionFunc = liftf(add) // Stores the new function in additionFunc
var result = additionFunc(1) // Evaluates the new function
Let's also look at IIFEs. Suppose we have one like this:
(function(x) {return x + 1})(5)
The (function() { /* ... */ }) expression evaluates to a function, which is then evaluated by the parentheses and argument (5).
Let's look at a simpler example of currying:
function add(x) {
return function (y) {
return x + y;
};
}
If you called it with only one argument, like so:
add(2);
It would expand to:
function (y) {
return 2 + y;
}
Which would expect a y argument (if you called it). You could run that like this:
function (y) {
return 2 + y;
}(5)
Or more succintcly:
add(2)(5);
Each function just expands to a new anonymous function when currying, so even though it looks weird, once you expand the code out, it will start to make sense.

Categories

Resources