Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the proper way of passing named functions to Javascript's higher-order functions?

I'm trying to use Javascript's higher-order functions for functional programming. However, they are producing unexpected results:

['1','2','3','4'].map(parseInt) // [1, NaN, NaN, NaN]

['1','2','3','4'].map(function(x){
    return parseInt(x)
}) // [1, 2, 3, 4]

I expected these two calls to Array.prototype.map to both return [1, 2, 3, 4]. How can I map parseInt() without using an anonymous function?

Similarly, I expected the following two expressions to produce the same value:

[4,6,8,3].reduce(Math.max,-Infinity) // NaN

[4,6,8,3].reduce(function(x,y){
    return Math.max(x,y)
},-Infinity) // 8

Also, since I'm new to functional programming in Javascript, please let me know if I'm using any terminology incorrectly.

like image 949
Leo Jiang Avatar asked Sep 03 '25 17:09

Leo Jiang


1 Answers

The problem are those optional arguments - that map and reduce pass to the callbacks, and that parseInt and Math.max unconcernedly accept.

What you basically need to do is fix their arity, so that they take only one resp. two arguments:

Function.prototype.ofArity = function(n) {
    var fn = this, slice = Array.prototype.slice
    return function() {
        return fn.apply(null, slice.call(arguments, 0, n));
    };
};

['1','2','3','4'].map(parseInt.ofArity(1)) // Array [1, 2, 3, 4]
[4,6,8,3].reduce(Math.max.ofArity(2), -Infinity) // 8

You might also want to take a look at Ramda, where all these methods are designed so that they work like that out of the box.

like image 86
Bergi Avatar answered Sep 06 '25 15:09

Bergi