This time let’s learn about Partial Application. Let’s take a look at the introduction of functions first. There is a brief introduction on the wiki:
In mathematics, a function describes the correspondence between each input value and a unique output value. The symbol is f(x). For example, the expression f(x)=x2 represents a function f in which each input value x is associated with a unique output value x2.
So, if an input value is 3, then its corresponding output value is 9. And g(x,y) = xy has two parameters x and y, and the product xy is the value. The function is described above (assuming that x and y are both ints for convenience), and two examples of the function are given. Let’s look at it in another way. f(x) can be expressed as: x -> y(x2) , that is, after mapping f to x2, it is written as int -> int.
Accepts an int and returns an int. Looking at g(x,y) again, it can be expressed as: x -> y -> z(xy). That is, x, y is mapped to z through g, written as int -> int -> int. Let’s look at the g(x,y) function and use JavaScript to implement it:
function g(x,y){
return x*y;
}
It’s perfect, very close to the mathematical definition. It accepts two parameters, x and y, in turn. And returns the product of the two of them. But when x is a constant, such as x=n (n is a natural number). Then g(n,y)=ny. This becomes the product of a constant and a variable, which accepts a parameter y and returns ny, that is, the mapping of y -> z(ny), written as int -> int. Therefore, we can understand the above work in this way, g(x,y) accepts a parameter int and returns a function int ->int. This returned function only accepts an int and returns an int. Let’s express it in javascript:
var h = g(2 );
h here represents the function h(y)=2y. In this way, h(5)=10, h(13)=26, etc.
h(5);
h(13) ;
This technique is to transform a function form that requires multiple parameters into a function chain that accepts a single parameter. It is usually called Curring. This is a name given in honor of Haskell Curry, but he is not 1st proposed. But unfortunately, javascript does not support such a feature. So to implement such a feature requires some work, which is not complicated. The main purpose is to store the parameters, and when waiting to call the next function in the function chain, take out the previous parameters and continue to pass them to the next function in the chain until the return value is finally obtained. Take a look at the following code first:
function atarr(a, index){
var index=index||0,args = new Array(a.length - index);
for(var i in a){
if(i>=index) args[i -index]=a[i];
}
return args;
}
function m(scope,fn){
if(arguments.length<3) return fn.call( scope);
var p = atarr(arguments,2);
return function(){
var args = atarr(arguments);
return fn.apply(scope,p.concat(args ));
}
}
Test code:
var plus = function(a,b){
return a b;
};
var plus2 = m(null,plus,2);
console.log(plus2(10));
console.log(plus2(0));
//Result
12
2
This is our goal It’s been implemented. The atarr function above takes out the parameters starting at the specified position in the arguments object and saves them into an array. The m function is the protagonist. It completes the tasks defined previously, saving the parameters on the function chain and returning the function that accepts the remaining parameters. The plus function in the test code originally accepted two parameters, a and b, and returned the sum of a and b, that is, int -> int -> int. However, plus2 now accepts one parameter, b, plus 2, and returns The sum of 2 and b is int -> int.
Through some of the above work, we implemented Partial Application in javascript, and hitch2 implemented domain binding and partial in the dojo framework. If you are interested, you can read its source code, it is also very simple and clear.