什么是函数式编程

匿名 (未验证) 提交于 2019-12-03 00:37:01

函数式编程在耳边回响了多年,今天就来详细了解一下它吧。

函数式编程的主要特征是:函数是一等公民。它建议大家写纯函数、没有副作用的函数。

讨论完纯函数的内容,我们会看一下最重要的应用:函数的柯里化。

纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。其中的副作用指的是:跟函数外部环境发生的交互。包括但不限于:

  • 更改文件系统
  • 往数据库插入记录
  • 发送一个 http 请求
  • 可变数据
  • 打印/log
  • 获取用户输入
  • DOM 查询
  • 访问系统状态

例如:slice是纯函数而splice不是。

var memoize = function(f) {   var cache = {};    return function() {     var arg_str = JSON.stringify(arguments);     cache[arg_str] = cache[arg_str] || f.apply(f, arguments);     return cache[arg_str];   }; };  var squareNumber  = memoize(function(x){ return x*x; }); squareNumber(4); //=> 16 squareNumber(4); // 从缓存中读取输入值为 4 的结果 //=> 16

值得注意的一点是,可以通过延迟执行的方式把不纯的函数转换为纯函数:

var pureHttpCall = memoize(function(url, params){   return function() { return $.getJSON(url, params); } });

纯函数对于依赖很诚实,这样就能知道它的目的。可以说是把所有需要的(可变的)参数都传递进来。

简单地给函数一个输入,就能有输出了。

如果一段代码可以替换成它执行所得的结果,而且是在不改变整个程序行为的前提下替换的,那么我们就说这段代码是引用透明的。这样会对理解代码非常重要,因为“可以使用等式推导”(equational reasoning)的技术来分析代码,就是“一对一”替换的情况下手动执行代码。

最后一点,也是决定性的一点:我们可以并行运行任意纯函数。因为纯函数根本不需要访问共享的内存,而且根据其定义,纯函数也不会因副作用而进入竞争态(race condition)。

并行代码在服务端 js 环境以及使用了 web worker 的浏览器那里是非常容易实现的,因为它们使用了线程(thread)。不过出于对非纯函数复杂度的考虑,当前主流观点还是避免使用这种并行。

curry 的概念很简单:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

function curry(fn) {   return function finalCurry(...args) {     if (args.length >= fn.length) {       return fn(...args);     } else {       return function (...args2) {         return finalCurry.apply(null, args.concat(args2));       }     }   } }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!