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