函数式编程是否避免状态?

Muh*_*uri 17 f# functional-programming

根据维基百科:函数式编程是一种编程范式,它将计算视为数学函数的评估,并避免状态和可变数据.(强调我的).

这是真的吗?我个人的理解是,它使状态更明确,因为编程实质上是将函数(变换)应用于给定状态以获得转换状态.特别是像monad这样的结构允许你通过函数显式地携带状态.我也不认为任何编程范式都可以完全避免状态.

那么,维基百科的定义是对还是错?如果它是错误的,那么定义函数式编程的更好方法是什么?

编辑:我想这个问题的核心是什么是国家?您是否了解状态是变量或对象属性(可变数据)还是不可变数据也是状态?举个例子(在F#中):

let x = 3
let double n = 2 * n
let y = double x
printfn "%A" y
Run Code Online (Sandbox Code Playgroud)

你会说这个片段是否包含状态?

编辑2:感谢大家的参与.我现在明白这个问题更多的是语言上的差异,使用了state一个社区与另一个社区不同的词,正如布莱恩在评论中提到的那样.特别是,功能编程社区中的许多人(主要是Haskellers)解释state为携带一些动态状态,如随时间变化的信号.state诸如有限状态机,Representational State Transfer无状态网络协议之类的其他用途可能意味着不同的东西.

Chu*_*uck 21

我认为你只是以一种不同寻常的方式使用"国家"一词.如果你考虑添加1和1来使2成为有状态,那么你可以说函数式编程包含状态.但是当大多数人说"状态"时,它们意味着存储和更改值,这样调用函数可能会留下与调用函数之前不同的东西,并且使用相同的输入第二次调用函数可能不会产生相同的结果.

从本质上讲,无状态计算是这样的:

  • 1 + 1的结果
  • 由"s"组成的字符串前置于"池"
  • 给定矩形的区域

有状态计算是这样的:

  • 增加一个计数器
  • 从数组中删除元素
  • 将矩形的宽度设置为现在的两倍

  • 是的,我认为这种"国家"的一个重要方面是它对时间的依赖.在命令式语言中,您进行排序操作(因此逐步改变状态)真正纯粹的功能程序没有固有的时间或顺序概念.他们只是"是".当然,如果你想执行这样的程序,运行时必须以某种"有意义"的方式将其映射到随时间变化的状态. (2认同)

Ran*_*pho 8

而不是避免状态,像这样想:

它避免了改变状态.那个词"可变".

考虑C#或Java对象.通常,您将在对象上调用一个方法,并且您可能希望它通过该方法调用来修改其内部状态.

通过函数式编程,您仍然可以获得数据,但它只是通过每个函数,创建与输入和操作相对应的输出.

至少在理论上.实际上,并非你所做的一切实际上都是功能性的,所以你经常最终隐藏状态以使事情有效.

编辑:
当然,隐藏状态也经常导致一些壮观的错误,这就是为什么你应该只使用函数式编程语言的纯函数情况.我发现最好的语言是面向对象功能性的语言,如Python或C#,它们为您提供两全其美的优势,并在必要时自由移动.

  • 你能详细说明一些"壮观的虫子"吗?此外,恕我直言Python和C#作为功能语言相当差. (9认同)
  • _"最好的语言是面向对象和功能的语言"_Scala,F#和OCaml符合要求.;)同意@Mauricio,Python和C#是对象功能语言的相当差的例子. (8认同)
  • @Mauricio:Python和C#是OO语言,增加了功能支持.它们不是纯函数式语言.我很抱歉我不明白.至于壮观的虫子......你知道吗,我想不出任何副手?他们主要是在UI,IIRC,但是......我没有.抱歉. (4认同)