Functional JavaScript
目錄
- 1 Get Started with FP
- 2 First-class Functions and Applicative Programming
- 3 Variable Scope and Closures
- 4 High-order Functions
- 5 Function-Building Functions
- 6 Recursion
- 7 Purity, Immutability and Policies for Change
- 8 Flow-based Programming
- 9 Programming without Class
- 10 Appendix
Get Started with FP
- CSV parse:
-
return _.reduce(str.split("\n"), function(table, row){
table.push(_.map(row.split(","), function(cell){return cell.trim();})); return table;}, []); };
-
- 作者是ClojureScript的作者?
First-class Functions and Applicative Programming
- return _.reduceRight(arguments, function(truth,f){ return truth && f(); }, true);
- 傳遞null作為第一個參數給apply:意味着this引用全局對象...
- p44 傳統的SQL Select實際上對應關系代數裡的Project
- JS的lambda文法太麻煩,給寫FP風格的代碼帶來了麻煩
-
restrict( project( as(library, {ed: 'edition'}), ['title','isbn','edition']),
function(book){ return book.edition>1; } );
-
Variable Scope and Closures
High-order Functions
Function-Building Functions
-
function partial(fun ){
var pargs = _.rest(arguments);
return function(){
var args = cat(pargs, _.toArray(arguments));
return fun.apply(fun, args);
} }
Recursion
- trampoline(避免mutual-recursive溢出):
- function even(n){ if(n==0) return true; else return partial1(odd, n-1); }
- ==> odd(20000001)()()...();
-
function trampoline(fun ){
var result = fun.apply(fun, _.rest(arguments)); //又來了
while(_.isFunction(result)) result = result();
return result; }
- function even(n){ if(n==0) return true; else return partial1(odd, n-1); }
- generator(惰性無限序列)
- head-tail()抽象,其中,tail封裝了“剩餘序列的計算”
-
function genTake(n, gen){
var doTake = function(x, g, ret){ if(x==0)return ret; else return partial(doTake, x-1, genTail(g), cat(ret, genHead(g)));}
return trampoline(doTake, n, gen, []);
Purity, Immutability and Policies for Change
- Object#freeze => deepFreeze
- API:讓對象修改方法傳回新對象執行個體
Flow-based Programming
- _.chain
- LazyChain
- thunk:a function waiting to be called
- #force()
- jQuery $.Deferred()
- Pipelining
- Action(Monad):flowing in context?
- lift
- actions
Programming without Class
- Mixins
- var polyToString = dispatch( function(s){ return _.isString(s)? s : undefined; }, ...
-
var MyMixin = {
setValue: function(v){ ... this._value = v; this.notify(oldVal, v); }
- _.extend(MyClass.prototype, MyMixin);
- var CAS = function(val){ MyClass.call(this, val); }
- var CASMixin = ...
Appendix
- Underscore-contrib
- RxJS
- Bilby's multimethods
- allong.es:support for stateful iterators
- *Reducers:inspired by Clojure's reducer
- ClojureScript(作者就是寫《The Joy of Clojure》的?)
- CoffeeScript
- Literate程式設計
- Varargs
- 清單了解
- 解構指派
- Roy:inspired by ML
- Elm(+不用作字元串拼接,需要用++):FRP