抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

一直追求”见字如面“、“代码自解释”的我,终于遇到了一种编程范式:函数式编程,高度抽象的语法使得代码如诗一样,总结一下学习成果。

主角

Introduction · 函数式编程指北 (gitbooks.io)

Why ?

计算机语言根据抽象层次划分了等级,底层的语言如,C、汇编,其更贴近计算机,抽象程度低,执行效率高;而高级的语言如 Java,PHP,C#,其更贴近计算,抽象程度较高,执行效率低,而函数式编程则是在其基础上又一次抽象,抽象程度更高,更贴近人类思维,以至于忘记计算机内部原理也可以编码,离计算机硬件越来越远。

一些代码规范

之前看大家写代码,总有一种不明所以的感觉,那种感觉就是感觉他写的不好,又不知道怎么描述,或者用我的写法又有什么优点。了解一下函数式编程的思维,才让我豁然开朗,现在我可以说为什么不好,怎么改,改过之后好在哪里?

一些代码总有一些:可变状态(mutable state)、无限制副作用(unrestricted side effects)和无原则设计(unprincipled design)的问题。

看下面这个例子:

// 不纯的
const signUp = function(attrs) {
  const user = saveUser(attrs);
  welcomeUser(user);
};

const saveUser = function(attrs) {
    const user = Db.save(attrs);
    ...
};

const welcomeUser = function(user) {
    Email(user, ...);
    ...
};

saveUser 函数内,有个 Db 对象在偷偷搞小动作!假如把该函数模块化复用,明显是跑不起来的,因为缺少 Db 对象,这种代码导致不可移植,正确的写法应该是提前将所有需要的变量放到形参里,并且 signUp 应该总是返回函数,保证它是纯的,如下

// 纯的
var signUp = function(Db, Email, attrs) {
  return function() {
    var user = saveUser(Db, attrs);
    welcomeUser(Email, user);
  };
};

var saveUser = function(Db, attrs) {
    ...
};

var welcomeUser = function(Email, user) {
    ...
};

这个例子表明,纯函数对于其依赖必须要诚实,这样我们就能知道它的目的。仅从纯函数版本的 signUp 的签名就可以看出,它将要用到 DbEmailattrs,这在最小程度上给了我们足够多的信息。

当然还有更多原则:DRY(不要重复自己,don’t repeat yourself),高内聚低耦合(loose coupling high cohesion),YAGNI (你不会用到它的,ya ain’t gonna need it),最小意外原则(Principle of least surprise),单一责任(single responsibility)等等。

关于纯函数的的概念:第 3 章: 纯函数的好处 · 函数式编程指北 (gitbooks.io)

写代码不难,写好才难

基础

curry

首先要先搞明白curry(函数柯里化),它让我们的代码得以优雅地不需要一次把所有参数都传入,只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

var add = function(x) {
  return function(y) {
    return x + y;
  };
};

var increment = add(1);
var addTen = add(10);

increment(2);
// 3

addTen(2);
// 12

借助 Ramda,可以写成

Ramda 中文文档

import * as R from "ramda";
const add = R.curry((x, y) => {
  return x + y;
});

compose

另一个是代码组合(compose)

var compose = function(f,g) {
  return function(x) {
    return f(g(x));
  };
};
const strReverse = compose(join, reverse, split);

splitReverse("hello world!");

不写了,下周天继续研究

评论