functional-programming - 纯函数式语言真的能保证不变性吗?

标签 functional-programming immutability purely-functional

在纯函数式语言中,难道还不能定义一个“赋值”运算符,比如“<-”,这样命令,比如“i <- 3”,而不是直接分配不可变变量 i,会创建整个当前调用堆栈的副本,​​除了用新调用堆栈中的 3 替换 i 并从那时起执行新调用堆栈?鉴于没有实际更改数据,根据定义,这是否仍被视为“纯功能”?当然,编译器会简单地进行优化,将 3 简单地分配给 i,在这种情况下,命令式和纯函数式之间有什么区别?

最佳答案

纯函数式语言,例如 Haskell,有对命令式语言建模的方法,而且它们也毫不避讳地承认这一点。 :)

http://www.haskell.org/tutorial/io.html ,特别是 7.5:

So, in the end, has Haskell simply re-invented the imperative wheel?

In some sense, yes. The I/O monad constitutes a small imperative sub-language inside Haskell, and thus the I/O component of a program may appear similar to ordinary imperative code. But there is one important difference: There is no special semantics that the user needs to deal with. In particular, equational reasoning in Haskell is not compromised. The imperative feel of the monadic code in a program does not detract from the functional aspect of Haskell. An experienced functional programmer should be able to minimize the imperative component of the program, only using the I/O monad for a minimal amount of top-level sequencing. The monad cleanly separates the functional and imperative program components. In contrast, imperative languages with functional subsets do not generally have any well-defined barrier between the purely functional and imperative worlds.



因此,函数式语言的值(value)不在于它们使状态变化成为不可能,而是它们提供了一种方法,允许您将程序的纯函数部分与状态变化部分分开。

当然,您可以忽略这一点并以命令式风格编写整个程序,但是这样您就不会利用该语言的功能,那么为什么要使用它呢?

更新

你的想法没有你想象的那么有缺陷。首先,如果只熟悉命令式语言的人想要遍历一系列整数,他们可能想知道如何在没有增加计数器的方法的情况下实现这一点。

但当然,您只需编写一个充当循环体的函数,然后让它调用自身。函数的每次调用都对应一个“迭代步骤”。并且在每次调用的范围内,参数具有不同的值,就像一个递增的变量。最后,运行时可以注意到递归调用出现在调用的末尾,因此它可以重用函数调用堆栈的顶部而不是增加它( tail call )。即使是这个简单的模式也几乎具有您的想法的所有风格 - 包括编译器/运行时悄悄介入并实际发生突变(覆盖堆栈顶部)。它不仅在逻辑上等同于一个带有可变计数器的循环,而且实际上它使 CPU 和内存在物理上做同样的事情。

你提到了 GetStack这会将当前堆栈作为数据结构返回。这确实违反了功能纯度,因为它每次被调用时必然会返回不同的东西(没有参数)。但是函数如何CallWithStack ,您将自己的函数传递给它,它会回调您的函数并将当前堆栈作为参数传递给它?那完全没问题。 CallCC有点像那样。

关于functional-programming - 纯函数式语言真的能保证不变性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5607165/

相关文章:

scala - 类型类解析中的隐式类别

functional-programming - 在函数式编程中,您将这种操作称为什么?

java - 使用不同的方法设置对象的多个字段

javascript - 如何在没有突变的情况下使用 javascript Map

C++ 编译时检查副作用

haskell - 如何准确衡量减少 λ 项所需的工作量?

list - 为什么 Haskell 列表的 `++` 是递归实现的并且花费 O(n) 时间?

c# - 为什么我不能更改 String.Empty 的值?

purely-functional - Clean 中的模函数

functional-programming - 在纯函数式语言中,数据(字符串、整数、 float ……)也只是函数吗?