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

在纯函数式语言中,不能仍然定义一个“赋值”运算符,比如“< - ”,这样命令就像“i< - 3”,而不是直接赋值不可变变量i,会创建整个当前调用堆栈的副本,​​除了在新调用堆栈中用3替换i,并从该点开始执行新的调用堆栈?鉴于实际上没有数据发生变化,根据定义,这仍然不会被视为“纯功能”吗?当然编译器只是简单地将优化分配给i,在这种情况下,命令式和纯函数之间的区别是什么?     
已邀请:
Haskell并不容易给你内省或“执行”调用栈的方法,所以我不会太担心这个特殊的奇怪方案。然而,一般来说,人们可以使用不安全的“函数”来破坏类型系统,例如
unsafePerformIO :: IO a -> a
。这个想法是让违反纯度变得困难,而不是不可能。 实际上,在许多情况下,例如在为C库创建Haskell绑定时,这些机制是非常必要的......通过使用它们,您将从编译器中消除纯度证明的负担并自行处理。 有人建议通过禁止类型系统的这种颠覆来实际保证安全;我不太熟悉它,但你可以在这里阅读它。     
纯函数式语言(如Haskell)具有对命令式语言进行建模的方法,并且他们也不会羞于承认它。 :) 见http://www.haskell.org/tutorial/io.html,特别是7.5:   所以,最后,简单地说是Haskell   重新发明了势在必行的轮子?      从某种意义上说,是的。 I / O monad   构成一个小小的必要条件   Haskell内部的子语言,因此   程序的I / O组件可以   看似与普通的命令相似   码。但有一个重要的   差异:没有特别之处   用户需要处理的语义   用。特别是,等于   哈斯克尔的推理不是   损害。迫切的感觉   程序中的monadic代码没有   有损于功能方面的   哈斯克尔。经验丰富的功能   程序员应该能够最小化   的必要组成部分   程序,只使用I / O monad   最低限度的顶级   测序。 monad干净利落   分离功能和   命令式程序组件。在   对比,命令式语言   功能子集通常不会   两者之间有任何明确的障碍   纯粹的功能和命令   世界。 因此,函数式语言的价值不在于它们使状态变异不可能,而是它们提供了一种方法,允许您将程序的纯功能部分与状态变异部分分开。 当然,您可以忽略这一点,并以命令式的方式编写整个程序,但是您不会利用该语言的设施,那么为什么要使用它呢? 更新 你的想法没有你想象的那样有缺陷。首先,如果只熟悉命令式语言的人想要遍历一系列整数,他们可能想知道如何在没有增加计数器的方法的情况下实现这一点。 但是当然你只需要编写一个充当循环体的函数,然后让它自己调用。函数的每次调用对应于“迭代步骤”。并且在每次调用的范围内,参数具有不同的值,就像递增变量一样。最后,运行时可以注意到递归调用出现在调用的最后,因此它可以重用函数调用堆栈的顶部而不是增长它(尾调用)。即使这个简单的模式几乎具有你想法的所有风格 - 包括编译器/运行时悄悄地插入并实际发生突变(覆盖堆栈的顶部)。它不仅在逻辑上等同于具有变异计数器的循环,而且实际上它使CPU和内存在物理上做同样的事情。 你提到一个将当前堆栈作为数据结构返回的
GetStack
。这确实会违反功能纯度,因为每次调用时它都必须返回不同的东西(没有参数)。但是如果函数
CallWithStack
,你传递一个自己的函数,它会回调你的函数并将当前堆栈作为参数传递给它?那将是完全可以的。 CallCC的工作方式有点像。     
不变性是语言的属性,而不是实现的属性。 如果从程序员的角度来看,参考位置
a
的值似乎已经改变,则复制数据的操作
a <- expr
仍然是必要的操作。 同样,纯函数式语言实现可以覆盖并重用变量到其内容,只要每个修改对程序员是不可见的。例如,只要语言实现可以推断出在任何地方都不需要旧列表,
map
函数原则上可以覆盖列表而不是创建新列表。     

要回复问题请先登录注册