Foreword In the previous article, Typical High-Order Functions in JavaScript, several typical functional functions were mainly implemented. The article also raised the question at the end, why is that implementation "different" from functional languages such as F#? Let’s try a more “functional” implementation today.
Another implementation Similarly, try to make some changes to the previously implemented function and remove the for loop. How to remove it? Here we first introduce the inductive definition of a set:
A set is either an empty set, or a number pair consisting of a number and a set. From the definition, we can see that each set can be regarded as a number. and a set of pairs. For example: {1,2,4,5} can be considered as a pair consisting of the number 1 and the set {2,4,5}, written as (1, {2,4,5}). Recursively, {2,4,5} can be viewed as (2, {4,5}). Finally, it is (5, Ø). Based on this understanding, we can use recursive methods to eliminate loops, because we have visited every data item during decomposition, and the terminal condition is the empty set. Let’s take a look at another implementation of the filter function. The original function name is prefixed with f to distinguish it from the previous function:
function ffilter(arr,callback){
var i=arguments[2] || 0,
out = arguments[3] || [];
if (!arr[i]) return arguments[3];
if(callback(arr[i]))
out.push(arr[i]);
return arguments.callee(arr,callback , i,out);
}
Test:
var arr = [1,2,3,4,5,6,7,8,9,10];
var even = function(item){
if( typeof item !== "number") return false;
return !(item & 1);
};
console.log(ffilter(arr,even));
Result:
[2, 4, 6, 8, 10] After eliminating the loop, it is closer to the inductive definition of mathematics and appears more natural. Similarly, look at the ffold function again:
var arr = [1,2,3,4,5,6,7,8,9,10];
var plus = function(a,b){
return a b;
};
console .log(ffold(arr,plus,3));
Result:
58
Use the same method for other functions. This feels more functional, but can it be closer to the mathematical definition? Try again next time.
==========2013.1.8 Update==================
As mentioned above, whether the writing methods can be closer to the mathematical definitions , let’s try using a linked list. First give a definition:
var node = function() {
this.data = 0;
this.tail = null;
};
Initialize another linked list :
var n1 = new node(),n2 = new node(),n3 = new node(),n4 = new node(),n5 = new node();
n1.data=1,n1.tail=n2;
n2.data=2,n2.tail=n3;
n3.data=3,n3.tail=n4;
n4.data=4,n4.tail=n5;
n5.data=5,n5.tail=null;
fold linked list version:
function lfold(head,callback ,b){
if(!head) return b;
else return callback(head.data,arguments.callee(head.tail,callback,b));
}
Output result:
18
According to the previous definition, a set is either an empty set, or a pair consisting of a "head" and a "tail" (set). Each time the function is called, it is decomposed into head and tail until the set is empty (after writing the above lfold function, I really feel that it is so perfect, it is simply a definition. If the program looks like this, there will be no need for comments. It is really a pleasure) . This is the expression closest to the mathematical definition. Because JavaScript does not support many functional language matches, it cannot be "automatically" decomposed, and it cannot directly express inductive definitions.
In addition to the above things, JavaScript can also implement partial in functional expressions. Hitch in the Dojo framework achieves this function. This is another obvious example of functional expressions being close to mathematics. I will discuss this in my next blog.