为什么函数式编程好?

时间:2012-02-29 06:34:55

标签: functional-programming

我注意到许多功能编程狂热分子都坚持某些核心概念:

  • 避免状态

  • 避免可变数据

  • 最大限度地减少副作用

  • 等...

我不仅仅想知道函数式编程还有什么其他东西,但为什么这些核心思想是好的呢?为什么避免国家和其他方面都很好?

4 个答案:

答案 0 :(得分:13)

简单的答案是,如果您没有额外的状态需要担心,您的代码更容易理解。更简单的代码更易于维护。您不需要担心特定代码(如函数)之外的事情来修改它。这对测试这样的事情有非常有用的影响。如果您的代码不依赖于某些状态,那么为该代码创建自动化测试会变得更加容易,因为您不必担心初始化某些状态。

拥有无状态代码使得创建线程程序变得更加简单,因为您不必担心同时修改/读取共享数据的两个执行线程。您的线程可以运行独立的代码,这可以节省大量的开发时间。

基本上,避免状态会创建更简单的程序。在某种程度上,存在较少的“移动部件”(即,代码行可以交互的方式),因此这通常意味着代码更可靠并且包含更少的故障。基本上,代码越简单,就越不会出错。对我而言,这是编写无状态代码的本质。

创建无状态的“功能”代码还有很多其他原因,但对我来说,这些代码都归结为简单。

答案 1 :(得分:5)

除了@Oleksi所说的,还有另一个重要的事情:参考透明度和事务数据结构。当然,您不需要使用函数式编程语言,但使用它们会更容易。

保证

Purely functional data structures保持不变 - 如果一个函数返回一个树,它将始终是同一个树,所有进一步的转换将创建它的新副本。以这种方式回溯到任何先前版本的数据结构要容易得多,这对许多基本算法都很重要。

答案 2 :(得分:5)

通常,函数式编程意味着:

  • 鼓励使用(一流)功能
  • 不鼓励使用(可变)状态

为什么突变是个问题?想想看:突变是数据结构goto控制流量。也就是说,它允许你以一种相当非结构化的方式任意“跳”到完全不同的东西。因此,它偶尔会有用,但大多数时候对可读性,可测试性和组合性都有害。

答案 3 :(得分:2)

一个典型的功能特征是“无子类型”。虽然把它称为一个特征听起来有点奇怪,但它有两个(某种程度上相关)的原因:

  • 子类型关系导致一系列不那么明显的问题。如果你不限制自己的单一或混合继承,你最终会遇到钻石问题。更重要的是你必须处理方差(协方差,逆变,不变性),这很快就会变成一场噩梦,特别是对于类型参数(a.k.a.genener)。还有几个原因,即使在OO语言中,您也会听到“首选组合而非继承”这样的陈述。
  • 另一方面,如果你只是省略了子类型,你可以对你的类型系统进行更多详细说明,从而可以进行(几乎)完整的类型推断,通常使用Hindley Milner类型推断的扩展来实现。

当然有时你会错过子类型,但是像Haskell这样的语言已经找到了一个很好的答案:类型类,它允许为几个定义一种常见的“接口”(或“一组常用操作”)否则不相关的类型。与OO语言的不同之处在于,类型类可以“之后”定义,而无需触及原始类型定义。事实证明,您可以使用类型类来完成几乎所有可以使用子类型的操作,但是以更灵活的方式(并且不会阻止类型推断)。这就是为什么其他语言开始采用类似的机制(例如Scala中的隐式转换或C#和Java 8中的扩展方法)