什么算作副作用?为什么内存分配没有副作用?

时间:2016-11-30 17:24:17

标签: haskell functional-programming monads side-effects

我理解像Haskell这样的纯函数式语言的吸引力,你可以使用monad跟踪磁盘I / O等副作用。

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

那么为什么是副作用而不是什么不是为什么绘制线?它只是在最“有用”的地方吗?还是有更多的理论基础?

2 个答案:

答案 0 :(得分:11)

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

编程语言实际上并不是一个实际的实现,所以除非您考虑将Cog C ++作为语言的一部分进行内存分配和系统调用,否则系统原语处理的高级语言&# 39;不是语言的一部分。如果它不是语言的一部分,那么它就不是副作用。

现在实际的实现机器代码永远不会是纯粹的,因为传递参数和接收返回值的方式是通过变异存储在寄存器或堆栈中。我们在所有现代编程中使用的大多数概念都转化为算术,标志,跳转和内存访问。除NOP之外的每条CPU指令都会使机器发生变形。仅由NOP组成的程序不是很有用。

答案 1 :(得分:8)

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

在当代硬件和操作系统上,Haskell的某些实现会在运行代码的过程中分配堆栈/堆,但是从代码中无法观察到它。