SoFunction
Updated on 2025-03-03

A brief discussion on anti-currying in JS

Anti-Curriization

On the contrary, the role of anti-currying is in the applicability of the enlarged function, so that functions originally possessed by a specific object can be used by any object.

That is, sign the function given below,

(arg1, arg2)

Convert to a function form, with the signature as follows:

func(obj, arg1, arg2)

This is the formal description of anti-Curriization.

For example, a simple implementation below:

 = function() {
  var that = this;
  return function() {
    return (that, arguments);
  }
};

function sayHi () {
  return "Hello " +  +" "+[].(arguments);
}
var sayHiuncurrying=();
(sayHiuncurrying({value:'world'},"hahaha"));

explain:

  • uncurrying is a method defined on the prototype of the Function, so this method can be used for all functions. When calling: sayHiuncurrying=(), so this in uncurrying points to the sayHi function; (This in general prototype method does not point to the prototype object prototype, but to the calling object. Here the calling object is another function, and the function is also an object in javascript)
  • (that, arguments) Set that to the context of the call method, and then pass arguments to the call method. In the previous example, that actually points to sayHi, so calling saysHiuncurrying(arg1, arg2, ...) is equivalent to (arg1, arg2, ...);
  • (arg1, arg2, ...), call function treats arg1 as the context of sayHi, and then passes the remaining parameters such as arg2,... to sayHi, so it is equivalent to (arg2,...);
  • Therefore, this is equivalent to sayingHiuncurrying(obj,args) equals (args).

Finally, we look at it in reverse, in fact, anti-currying is equivalent to converting the original form of sayHi(args) into sayHiuncurrying(obj,args), which generalizes the scope of use of sayHi. Expressed more abstractly, uncurrying in anti-currying, so that the original (z) call can be converted into a call in the form of y(x',z). Assuming x' is x or other objects, this expands the scope of use of functions.

General anti-curry function

In the above example, uncurrying is written into prototype, which is not very good. We can actually encapsulate uncurrying into a function alone;

var uncurrying= function (fn) {
  return function () {
    var args=[].(arguments,1);
    return (arguments[0],args);    
  }  
};

The above function is very clear and direct.

When used, uncurrying is called and an existing function fn is passed in. The anti-currying function returns a new function. The first argument accepted by the new function will be bound to the context of this in fn, and other parameters will be passed to fn as parameters.

Therefore, a more popular explanation for anti-Curriization can be a borrowing of functions, which means that functions can accept processing other objects, and expand the scope of use of functions through borrowing and generalization.

Therefore, the more common usage of uncurrying is to second the other built-in methods of Javascript without implementing them all by yourself.

The text description is quite confusing, so continue to read the code:

var test="a,b,c";
((","));

var split=uncurrying();  //[ 'a', 'b', 'c' ]
(split(test,','));          //[ 'a', 'b', 'c' ]

split=uncurrying() passes a specific fn to uncurrying, that is, the split function has the function. When the function calls split(test,','), the first parameter passed is the context of split execution, and the remaining parameters are equivalent to being passed to the original function.

Let's take a look at another example:

var $ = {};
($.push);             // undefined
var pushUncurrying = uncurrying();
$.push = function (obj) {
  pushUncurrying(this,obj);
};
$.push('first');
($.length);            // 1
($[0]);              // first
($.hasOwnProperty('length'));   // true

Here we imitate a push method that borrows Array when implementing "jquery library". We know that objects do not have a push method, so () returns undefined, and can borrow Array to process push, and the native array method (js engine) maintains the length attribute and array members of the pseudo-array object.

By the same token, we can continue to have:

var indexof=uncurrying();
$.indexOf = function (obj) {
  return indexof(this,obj);
};
$.push("second");
($.indexOf('first'));       // 0
($.indexOf('second'));       // 1
($.indexOf('third'));       // -1

For example, when we implement our own class library, if some methods are similar to native methods, we can borrow native methods through uncurrying.

We can also uncurring the /apply method, for example:

var call= uncurrying();
var fn= function (str) {
  (+str);
};
var obj={value:"Foo "};
call(fn, obj,"Bar!");            // Foo Bar!

This allows you to use functions as ordinary "data" very flexibly. There is a way to use functional programming, and you can often see this usage in some class libraries.

Attack of the general uncurrying function

The uncurrying function above is a version that is more in line with thinking habits and is easy to understand. Let’s take a look at a few other versions:

First of all, if the B square is higher, uncurrying may also be written like this:

var uncurrying= function (fn) {
  return function () {
    var context=[].(arguments);
    return (context,arguments);
  }
};

Of course, if you need to upgrade B-frame, then it can be like this:

var uncurrying= function (fn) {
  return function () {    
    return (fn,arguments);
  }
};

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.