在函数式编程中如何避免副作用

Siv*_*iva 1 multithreading functional-programming scala concurrent-programming

我一直在比较Scala over Java在并发编程方面的优势.

显然,我提出的第一点是Scala是一种功能性编程语言(部分)使用FP自然避免了副作用

与命令式语言相比,函数式编程中如何避免副作用以及它如何在多线程/并发编程中工作?

Mat*_*zyk 5

我认为,该语句的含义是,Scala作为一种功能性OO 混合语言,鼓励(有时使其)使用功能结构和规则,这将导致无副作用.你可以用副作用编写非功能状态Scala代码;-)另一方面,你可以尝试编写函数式Java(例如),但由于函数不是第一类对象,它可能看起来很难看.所以我不会说它自然会如此,但更多的是在某些方面帮助你,并总体上鼓励你这样做.

那么在进行函数式编程时你应该坚持几个原则,结果不会产生任何副作用:

  • 不可变是好的 - 首选创建并且无法修改的结构.例如,在Java列表中,您可以修改第n个元素,但在Scala中,您将使用新元素返回该列表的副本.是的,这可能意味着程序中有更多对象,但也应该产生更多可重用且更安全的代码.
  • 将值作为参数传递,不将状态存储在成员变量中 - 共享状态是许多问题的原因并且管理共享状态是有问题的(例如,您需要使用锁等)
  • 更喜欢重新计算值如果它便宜,而不是缓存它们(这有一些例外规则,例如http://en.wikipedia.org/wiki/Memoization是一种非常常用的技术!)

实际上,通过遵循上述规则避免副作用的最大好处之一是更容易并发编程!毕竟,并发编程的最大障碍是管理共享状态!

由于其中一条规则是可变和共享状态不好,所以不要使用它!相反,许多函数式语言(例如Erlang或Scala)更喜欢所谓的Actor模型,其中Actors(可以与线程比较)只通过相互发送消息进行通信(参见?传递值而不是将它们存储在某处!).