Hey Underscore, You're Doing It Wrong! 觀後感
起因
Diro 分享了一個影片
以下簡單記錄我看完的心得
內容簡介
Speaker 是 Brian Lonsdorf (CTO of Loop/Recur, 多麼 geek 的公司名 XD)
LinkedIn: https://www.linkedin.com/in/drboolean
GitHub: https://github.com/DrBoolean
整個影片的重點在說明 Underscore 這個 library 雖然宣稱提供了一些有用的 functional programming helpers, 但是它的介面設計讓使用的人很難寫出真的 functional language 特性的 codes
Currying
以下他用幾個例子來說明 Underscore 的問題要看以下他舉的例子前, 先說明一個東西 - Currying
假設你有一個 function 叫 add
var add = function(x, y) {
return x + y;
}
假設你希望可以這樣寫var add2 = add(2); // return: function()
add2(10); // return: 12
add2(5); // return: 7
那你就要修改一下你的 add 定義var add = function(x) {
return function(y) {
return x + y;
}
}
var add2 = add(2); // return: function(y) {...}
add2(10); // return: 12
add2(5); // return 7
有更 generic 的作法, 請參考 http://blog.rx836.tw/blog/javascript-currying/作者也有提到一個幫你把你的 function 轉成 curried function 的 library (wu.js)
所以假設這樣寫會把你的 function 轉成 curried function\
var add = function(x, y) {
return x + y;
}.autoCurry();
舉幾個實際點的例子 (畢竟 add 有點沒感覺)var modulo = function(divisor, dividend) {
return dividend % divisor;
}.autoCurry();
modulo(3, 9); // return: 0
var isOdd = module(2);
isOdd(6); // return: 0
isOdd(7); // return: 1
var filter = function(f, xs) {
return xs.filter(f);
}.autoCurry();
filter(isOdd, [1, 2, 3, 4, 5]); // return: [1, 3, 5]
var getTheOdds = filter(isOdd);
getTheOdds([1, 2, 3, 4, 5]); // return: [1, 3, 5]
講者提的範例
- 範例一
var firstTwoLetters = function(words) {
return _.map(words, function(word) {
return _.first(word, 2);
});
};
firstTwoLetters(['jim', 'kate']); // return: ['ji', 'ka']
因為 Underscore 的參數順序是先 array 再 function所以沒辦法寫得更好
他認為如果 Underscore 能把參數順序顛倒且 API 是 curried functions
就可以寫成這樣
// _.first(n, array) 參數顛倒
var firstTwoLetters = function(words) {
return _.map(words, _.first(2));
};
// 更進一步, _.map(f, array) 參數顛倒
var firstTwo = _.map(_.first(2));
filterTwo(['jim', 'kate']);
- 範例二
var sortedPhones = function(users) {
return _.chain(users)
.sortBy(function(user) { return user.signup_date; })
.map(function(user) { return user.phone; })
.value();
};
sortedPhones(users);
他將其改寫為var sortedPhones = _.compose(
_.map(function(user){ return user.phone; }),
_.sortBy(function(useR){ return user.signup_date}));
sortedPhones(users);
更進一步var dot = function(prop, obj) {
return obj[prop];
}.autoCurry();
var sortedPhones = _.compose(_.map(dot('phone')),
_.sortBy(dot('signup_date')));
sortedPhones(users);
結論
我個人認為, 看完這個影片比看 Functional Javascript 這本書還更能感受 functional language 的特性 XD不過我也還不是很懂, 大家就一起學習吧
0 comments