函数式编程:副作用
大多数教程/文章/书籍都会讨论函数式编程时的副作用。拿这个Python代码来说:
def isPrime(n):
k = 2
while k < n:
if n % k == 0:
return False
k += 1
return True
文字说上面的函数有局部副作用,我不明白。我看到变量“k”正在改变,我不明白它会产生什么不好的结果。
有人可以给出一个明显的副作用的例子,以及如何通过函数式编程来避免它吗?
Most tutorials/articles/books talk about side effects when presenting functional programming. Take this Python code:
def isPrime(n):
k = 2
while k < n:
if n % k == 0:
return False
k += 1
return True
The text says that the above function has local side effects, and I don't understand that. I see that the variable "k" is changing, I don't understand what bad comes out of it.
Can someone please give a clear example of bad side effect, and how it is avoided by functional programming?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您所指的文本是正确的,更改局部变量被认为是副作用。
这并不是说这一定是一件坏事。它只是不是函数式编程。在纯函数式编程语言中,您可以以递归方式编写循环,从而无需更改变量。
在任何语言中编写这样的函数(没有明显的副作用)都是一种很好的做法,它只是不是函数式编程。
编辑:现在我看到你关于“坏”副作用的评论。我不会说副作用是不好的。在大多数主流语言中,没有它们就很难编程,而且我认为许多程序员都会从副作用的角度来考虑。但在大型软件项目中,过度依赖副作用可能会让你的生活变得非常痛苦。 这是一个涉及单例的很好的例子(导致副作用的最终方法)
在禁止副作用的语言中,对于程序员以及编译器来说,惊喜都会减少。纯函数代码更容易分析和并行化,并且至少在理论上更容易被编译器优化。
The text you're referring to is right, changing a local variable is considered a side effect.
It doesn't say that this is a bad thing necessarily. It is just not functional programming. In pure functional programming languages you would write the loop in a recursive way, eliminating the need for changing variables.
Writing functions like these (that have no observable side effects) is a fine practice in any language, it is just not functional programming.
Edit: Now I see your remark about "bad" side effects. I would not say that side effects are bad. In most mainstream languages, it is hard to program without them, and I think that many programmers think in terms of side effects. But in large software projects, relying too much on side effects can make your life pretty miserable. Here's a nice example involving singletons (the ultimate way to cause side effects)
In a language that forbids side effects, there are less surprises for you as a programmer, but also for the compiler. Pure functional code is easier to analyze and paralellize, and is, at least theoretically, easier to optimize by the compiler.
副作用(特别是没有引用透明度)使得 结果您的代码取决于语句的执行顺序。因此,更改某些函数调用对的调用顺序可能会改变程序中断开连接区域的行为。这是因为由于共同承担副作用,它们并没有真正断开连接。
这使得程序的分解变得难以令人难以置信,从而使用新代码组合现有代码或以其他方式隔离和分离出代码任何部分的功能的尝试变得令人沮丧。换句话说,副作用就像尸僵胶水一样,会溅到所有东西上,使其成为一根无法穿透的意大利面条。尝试拉出一根面条,不要对大多数其他面条造成一连串的干扰。
Side-effects (specifically not having referential transparency) make the result of your code depend on the order of execution of the statements. Thus a change to the order of invoking some pair of function calls, could possibly alter behavior in a disconnected area of your program. This is because they weren't really disconnected, due to the mutual sharing of side-effects.
This makes the decomposition of your program difficult to implausible, thus frustrating attempts to compose your existing code with new code, or otherwise isolate and separate out the functionality of any portion of your code. In other words, side-effects are like Rigor Mortis glue that spills on everything and causes it to be one impenetrable monolithic spaghetti. Try to pull out one noodle, without causing a cascade of disturbance to most the other noodles.