什么算作副作用?为什么内存分配不是副作用?

What counts as a side-effect? Why isn't memory allocation a side-effect?

我理解 Haskell 等纯函数式语言的吸引力,您可以在其中使用 monad 跟踪磁盘 I/O 等副作用。

为什么不将所有系统调用都视为副作用?例如,未跟踪 Haskell 中的堆内存分配(自动分配)。堆栈分配可能是一个副作用,尽管我不确定它是否有用。这两者都会改变系统的整体状态。

那么什么是副作用,什么不是?是不是最多"useful"?还是有更多的理论基础?

堆栈分配和堆分配都不是您可以"do"或在Haskell中观察到的。因此,不能算作副作用。从某种意义上说,加热 CPU 也是如此,这无疑是 运行 纯 Haskel 代码的可识别物理效应。

碰巧 Haskell 在当代硬件和 OS 上的某些实现会在 运行 您的代码过程中分配堆栈/堆,但从您的代码中无法观察到代码。

在推理这些事情时,它必须在理论层面和语言规范层面,而不是在硬件上实际完成的方式。

编程语言并不是真正的实际实现,因此除非您考虑将内存分配和系统调用作为语言的一部分的 C og C++,否则由系统原语处理的高级语言不是语言的一部分。如果它不是语言的一部分,它就不可能是副作用。

现在,实际的实现机器代码永远不会是纯粹的,因为传递参数和接收 return 值的方式是通过突变存储在寄存器或堆栈中。我们在所有现代编程中使用的大多数概念都被转化为算术、标志、跳转和内存访问。除了 NOP 之外的每个 CPU 指令都会使机器发生变异。只包含NOP的程序用处不大