anyone can explain this code..? especially "action(i)" in for scope. i'm new in JS
function repeat(n,action){
for(let i= 1; i<=n; i++){
action(i);
}
}
repeat(10, console.log);
repeat(3, alert);
The code above simply repeats a given function (the action function) n amount of times, passing i (the current iteration) into the function
e.g.:
repeat(10, console.log);
That repeats console.log 10 times. console.log is a function, which is passed in as the action function. Then it is run 10 times.
Higher order function are functions that take other functions as parameter(s). It is based on functions being so-called first-class-members in Javascript, which says, among other things, this: functions can be passed to other functions, as parameters.
In your example the passed function inside the repeatfunction is called action, which is defined by your repeat function signature (n,action) (regardless of any name the actual function that is being passed in might already have), so whatever function gets passed into repeat is callable inside it using action().
Please note that there is no way to guarantee that the actual call will have a function as a second parameter; noone can prevent somebody from making calls like repeat('foo', 'bar') or even repeat(). It is your job as a developer to make your function failsafe in this regard, or to take the shit in, shit out standpoint.
A more simplified example would be this:
function showMessage(message, showMethod) {
showMethod(message);
}
showMessage('Hello world shown by console.log', console.log);
showMessage('Hello world shown by alert', alert);
showMessage('Hello world shown by console.error', console.error);
showMessage is a function that shows a message, which it expects to be the first parameter when it is called.
The actual function that should be used to display the passed message needs to be passed into showMessage as a second parameter.
When called, showMessage runs the function that was passed as a second parameter (which is renamed to showMethod inside showMessage), passing message to it.
Another more practical use case could be this:
function add(x, y) { return x + y; }
function subtract(x, y) { return x - y; }
function multiply(x, y) { return x * y; }
function divide(x, y) { return x / y; }
function calculate(x, y, calcFunction) {
const result = calcFunction(x, y);
return result;
}
console.log(calculate(2, 5, add));
console.log(calculate(2, 5, subtract));
console.log(calculate(2, 5, multiply));
console.log(calculate(2, 5, divide));
Related
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.
I came across this pattern in redux compose function. I still don't understand how in the example below the functions are evaluated starting from the last and not from the first:
function f2(a) {
return a + a;
}
function f3(a) {
return a + a + a;
}
function f4(a) {
return a + a + a + a;
}
function f5(a) {
return a + a + a + a + a;
}
function compose(...funcs) {
return funcs.reduce(function x(a, b) {
return function y(...args) {
const temp = a(b(...args));
return temp;
};
});
}
const composedFunction = compose(f2, f3, f4, f5);
const result = composedFunction(2);
In the first reduce iteration the accumulator is f2 so we'll get f2(f3(2))=12. In the next iteration we'll call f4(12)=48. In the last iteration we'll call f5(48)=240. So the evaluation order is f5(f4(f2(f3(2)))). But using console.log I see that the evaluation order is f2(f3(f4(f5(2)))) which is also 240 by coincidence.
As far as I understand the function y is called for all array elements so why only the last function gets 2 as the parameter?
Let's step through the code with a very simple example:
compose(f2, f3, f4)
As no initial value was passed to reduce, it will start with the first (f2) and the second (f3) value of the array and call the callback with that, x gets called with a being f2 and b being f3. Now x does'nt do anything, it just returns function y that can access a and b through a closure.
Reduce will now continue to the third element, the first argument being the result of the previous callback (the closured y), and the second argument being f4. Now x gets called again, and another closure is created over y, y gets the finally returned from the whole function.
If we try to visualize thus closured function it'll be:
y { // closure of y
a -> y { // a references another closure of y
a -> f3,
b -> f2
},
b -> f4
}
Now you call that closured y and pass 2 into it, that will call b (f4) and pass the result to the call to a (closured y).
a ( b(...args))
y { ... } ( f4(2) )
Now that closured y will do the same:
a ( b ( ...args))
f2( f3( f4( 2 ) ) )
Hint: It is sometimes really difficult to keep track of closured values, therefore the console provides you with great utilities to keep track of them: Open your code in the consoles "debugger" tab, click on the line numbers where the function calls are to attach breakpoints, then run the code again, the execution will yield whenever a breakpoint is reached and you can see the values of all variables (including closured ones).
The reduce is not calling the functions f2, f3, f3, f5, but it is creating a function from those. This is the value of the accumulator in each iteration. Note that the value is a function and not a result from execution of the function.
1:a=f2;b=f3;return value(NOT TEMP but function y)=f2(f3(...args))
2:a(prev return value)=f2(f3(...args));b=f4;return value=f2(f3(f4(...args)))
and so on....
The compose function can be re-written as:
function compose(...funcs) {
return funcs.reduce(function (a, b) {
return function (arg) {
const temp = a(b(arg));
return temp;
};
});
}
After the first iteration, the returned function which is passed in as the next accumulator is:
function (arg) { // R1
return f2(f3(arg));
}
After the second iteration, the returned function which is passed in as the next accumulator is:
function (arg) { // R2
return R1(f4(arg));
}
And finally, the returned function assigned to composedFunction is:
function (arg) { // composedFunction
return R2(f5(arg));
}
So running composedFunction(2) and going back up the chain:
f5(2) returns 10
R2(10) returns R1(f4(10))
which is R1(40)
R1(40) returns f2(f3(40))
which is f2(120)
which is 240
Hopefully that's sufficient.
It can be written as a single call as:
function composedFunction(arg) {
return f2(f3(f4(f5(arg))));
}
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.
Today, I saw the following code below:
log_execution_time = require('./utils').log_execution_time;
var fib = function fib(n) {
if (n < 2) return n;
return fib(n - 1) + fib(n - 2);
};
var timed_fib = log_execution_time(fib);
timed_fib(5);
>>> Execution time: 1.166ms
I am curious about function log_execution_time. I don't know how it is.
You can see the input of log_execution_time is a function. How can it call the function with parameter? But all of the methods from w3school need a parameter when calling a function. I assume:
var log_execution_time = function (input_function){
console.time("Execution time");
// input_function
console.timeEnd("Execution time");
}
Thanks and regards
I think the OP is specifically about how the 5 parameter gets passed to the function input_function
Functions are first class objects in JavaScript. You can set identifiers and pass their references around just the same as any other object.
log_execution_time(fib); does not invoke fib, it passes a reference to fib into the log_execution_time function as the first argument. This means the internals can reference fib
timed_fib is a function which can reference the closure from that invocation of log_execution_time due to when it was created, so it can hence invoke the reference to fib as desired
Here is a simple example;
function log(msg) {
console.log(msg);
}
function wrap(fn) {
return function () { // some anonymous function to be our wrapper
console.log('Wrapped:');
fn.apply(this, arguments); // this line invokes `fn` with whatever arguments
// that were passed into the anonymous function
};
}
var foo = wrap(log);
foo('Hello World'); // logs
// Wrapped:
// Hello World
We could also have used the more usual way to invoke fn, for example fn("fizz buzz");, instead of .apply but that would mean we needed to know more about how to invoke fn, which could have been anything
Useful stuff:
Function.prototype.apply
Function.prototype.call
This is known as function currying, in this case the function is being curried with a parameter that also happens to be a function. It may look something like this:
function logTime(f) {
return function() {
var s = new Date();
var r = f.apply(null, arguments);
var e = new Date();
console.log('Time taken ' + (e-s));
return r;
}
}
function numberlogger(n) {
console.log("logged number: " + n)
};
var timedlogger = logTime(numberlogger);
console.log(timedlogger(2));
We call logTime, passing in numberlogger as an argument. Functions in JavaScript are objects and can be passed around like anything else. The logTime function returns a different function that is then stored in timedlogger. When we invoke timedlogger, we're actually invoking the function that logTime returned. That uses a couple of variables to keep track of the start and end times for timing, but uses apply (which every function in js has) to call the original function (numberlogger) whilst passing in any arguments supplied.
I suggest reading up on Functions in Javascript. Here's a nice article from the Mozilla Developer Network (MDN) which is in my opinion, a much better resource than w3schools
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
To answer your question though, functions in javascript are first class citizens, and what that means is that you can think of them as any other object (string,boolean,number etc). They can be saved in variables and they can be passed as arguments into other functions.
In your example, log_execution_time will actually return a function which is essentially a wrapper around the fib function that gets passed to it
The code can be like this:
var log_execution_time = function (input_function){
var f=function(args)
{
var t1=new Date().getTime();
input_function(arguments);
console.warn("Execution time:" +(new Date().getTime()-t1).toString());
}
return f;
}
I'm getting around to learning JavaScript - really learning JavaScript. I come from a PHP background so some JavaScript concepts are still new to me, especially asynchronous programming. This question might have already been answered many times before but I have not been able to find an answer. It might be because I don't really even know how to ask the question other than by showing an example. So here it is:
When using the deferred package from npm, I see the following example:
delayedAdd(2, 3)(function (result) {
return result * result
})(function (result) {
console.log(result); // 25
});
They refer to this as chaining and it actually works as I'm currently using this code to check when a promise is resolved or is rejected. Even though they call it chaining, it reminds me of trailing closures like in Swift.
I don't really understand what type of chaining this is since we have a function invocation and then immediately after, an anonymous function enclosed in parentheses.
So I guess I have two questions.
What pattern is this?
How does it work? This may be a loaded question but I like to know how something works so when someone asks me about this I can give them a detailed explanation.
Here is the delayedAdd function:
var delayedAdd = delay(function (a, b) {
return a + b;
}, 100);
which uses the following function:
var delay = function (fn, timeout) {
return function () {
var def = deferred(), self = this, args = arguments;
setTimeout(function () {
var value;
try {
value = fn.apply(self, args));
} catch (e) {
def.reject(e);
return;
}
def.resolve(value);
}, timeout);
return def.promise;
};
};
It's actually really easy to understand. Let's look at what's going on here when the expression is evaluated:
First the delayedAdd(2, 3) function will be called. It does some stuff and then returns. The "magic" is all about its return value which is a function. To be more precise it's a function that expects at least one argument (I'll get back to that).
Now that we evaluated delayedAdd(2, 3) to a function we get to the next part of the code, which is the opening parenthesis. Opening and closing parenthesis are of course function calls. So we're going to call the function that delayedAdd(2, 3) just returned and we're going to pass it an argument, which is what gets defined next:
That argument is yet another function (as you can see in your example). This function also takes one argument (the result of the computation) and returns it multiplied by itself.
This function that was returned by the first call to delayedAdd(2, 3) returns yet another function, which we'll call again with an argument that is another function (the next part of the chain).
So to summarize we build up a chain of functions by passing our code to whatever function delayedAdd(2, 3) returned. These functions will return other functions that we can pass our functions again.
I hope this makes the way it works somewhat clear, if not feel free to ask more.
mhlz's answer is very clear. As a supplementary, here I compose a delayedAdd for your to better understand the process
function delayedAdd(a, b) {
var sum = a + b
return function(f1) {
var result1 = f1(sum)
return function(f2) {
f2(result1)
}
}
}
Where in your example code, the function you passed as f1 is:
function (result) {
return result * result
}
and f2 is:
function (result) {
console.log(result)
}
Functions are first-class citizens in JS - that means (among others), they can take the role of actual parameters and function return values. Your code fragment maps functions to functions.
The signatures of the functions in your chained call might look like this.
delayedAdd: number -> fn // returns function type a
a: fn ( number -> number) -> fn // returns function type b
b: fn ( number -> void ) -> void // returns nothing ( guessing, cannot know from your code portion )
General setting
Of course, JS is a weakly typed language, so the listed signatures are derived from the code fragment by guessing. There is no way to know whether the code actually does what is suggested above apart from inspecting the sources.
Given that this showed up in the context of 'chaining', the signatures probably rather look like this:
delayedAdd: number x number -> fn (( fn T -> void ) -> ( fn T -> void ))
Which means that delayedAdd maps two numbers to a function x, which maps functions of arbitrary signatures to functions of the same signature as itself.
So who would do anything like this ? And why ?
Imagine the following implementation of x:
//
// x
// Collects functions of unspecified (possibly implicit) signatures for later execution.
// Illustrative purpose only, do not use in production code.
//
// Assumes
function x ( fn ) {
var fn_current;
if (this.deferred === undefined) {
this.deferred = [];
}
if (fn === undefined) {
// apply functions
while ( this.deferred.length > 0 ) {
fn_current = this.deferred.shift();
this.accumulator = fn_current(this.accumulator);
}
return this.accumulator;
}
else {
this.deferred.push ( fn );
}
return this;
}
Together with a function delayedAdd that actually returns an object of the following kind ...:
function delayedAdd ( a1, a2) {
return x ( function () { a1 + a2; } );
}
... you'll effectively register a chain of functions to be executed at some later point of time (e.g. in a callback to some event).
Notes and reminders
JS functions are JS objects
The signatures of the registered functions may actually be arbitrary. Considering them to be unified just serves to keep this exposition simpler (well ...).
Caveat
I do not know whether the outlined codeis what node.js does (but it could be ... ;-))
To be fair this pattern can be either chaining or currying(or partial application). Depending how it's implemented. Note this is a theoretical answer to provide more information about the pattern and not your specific use case.
Chaining
There is nothing special here because we can just return a function that will be called again. Functions in javascript are first class citizens
function delayedAdd(x, y) {
// In here work with x and y
return function(fn) {
// In here work with x, y and fn
return function(fn2) {
//Continue returning functions so long as you want the chain to work
}
}
}
This make it unreadable in my opinion. There is a better alternative.
function delayedAdd(x, y) {
// In here work with x and y
return {
then: function(fn) {
// In here work with x, y and fn
return {
then: function(fn2) {
//Continue returning functions so long as you want the chain to work
}
}
}
}
}
This changes the way your functions are called from
delayedAdd(..)(..)(..); // 25
is transformed to
delayedAdd().then().then()
Not only is more readable when you are passing several callback functions but allows a distinction from the next pattern called currying.
Currying
The term cames after the mathematician Haskell Curry. The definition is this
In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument (partial application). It was introduced by Moses Schönfinkel and later developed by Haskell Curry.
Basically what it does is take several arguments and merge with the subsecuents and apply them to the original function passed in the first argument.
This is a generic implementation of this function taken from Stefanv's Javascript Patterns.
{Edit}
I changed my previous version of the function to one which has partial application included to make a better example. In this version you must call the function with no argument to get the value returned or you will get another partially applied function as result. This is a very basic example, a more complete one can be found on this post.
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = [],
partial = function () {
if (arguments.length === 0){
return fn.apply(null, stored_args);
} else {
stored_args = stored_args.concat(slice.call(arguments));
return partial;
}
};
return partial;
}
This are the results of the application of this function
function add(a, b, c, d, e) {
return a + b + c + d + e;
}
schonfinkelize(add)(1, 2, 3)(5, 5)(); ==> 16
Note that add (or in your case delayedAdd) can be implemented as the curying function resulting in the pattern of your example giving you this
delayedAdd(..)(..)(..); // 16
Summary
You can not reach a conclusion about the pattern just by looking at the way the functions are called. Just because you can invoke one after the other it doens't mean is chaining. It could be another pattern. That depends on the implementation of the function.
All excellent answers here, especially #mhlz and #Leo, I'd like to touch on the chaining part you've mentioned. Leo's example shows the idea of calling functions like foo()()() but only works for fixed number of callbacks. Here's an attempt to imlpement unlimited chaining:
delayedAdd = function da(a, b){
// a function was passed: call it on the result
if( typeof a == "function" ){
this.result = a( this.result )
}
else {
// the initial call with two numbers, no additional checks for clarity.
this.result = a + b;
}
// return this very function
return da;
};
Now you can chain any number of functions in () after the first call:
// define some functions:
var square = function( number ){ return number * number; }
var add10 = function( number ){ return number + 10; }
var times2 = function( number ){ return number * 2; }
var whatIs = function( number ){ console.log( number ); return number; }
// chain them all!
delayedAdd(2, 3)(square)(whatIs)(add10)(whatIs)(times2)(whatIs);
// logs 23, 35 and 70 in the console.
http://jsfiddle.net/rm9nkjt8/3/
If we expand this syntax logically we would reach something like this:
var func1 = delayedAdd(2, 3);
var func2 = function (result) {
return result * result
};
var func3 = function (result) {
console.log(result);
};
var res = func1(func2); // variable 'res' is of type 'function'
res(func3);