在Scala这样的混合语言中,应该在功能编程和命令式编程之间划清界限吗?

时间:2017-03-24 09:33:55

标签: scala functional-programming

函数式程序员经常会忽视命令式编程中使用的约定和方法,比如可变变量的使用,for循环的使用,显式异常的创建。

然而,如果深入研究Scala的库,人们会发现语言的功能优雅实际上是由半命令式实现封装的。

例如,考虑TraversableLike特性中forall的实现。

def forall(p: A => Boolean): Boolean = {
    var result = true
    breakable {
      for (x <- this)
        if (!p(x)) { result = false; break }
    }
    result
}

很容易认为所有函数式语言都是高级语言,并且实际上是建立在命令式基础之上,因为语言本身是使用命令式语言构建的。

但是,我的问题是,为了保持代码库符合功能标准,我们应该在命令式和函数式之间绘制类似的东西?

1 个答案:

答案 0 :(得分:1)

这主要是一个自以为是的问题,所以我会给出一个自以为是的答案。

Scala是一种允许命令式/ OOP程序员(尤其是Java程序员)发现函数式编程的语言。因此,它允许编码人员像在Java中那样做所有事情,但是给他们提供了(也是社区鼓励他们)进行函数式编程的可能性。

一旦您开始使用Scala作为函数式编程语言,您应该几乎不会使用var s,returnwhile循环等命令元素。

你的大多数编程应该以功能的方式完成,以允许这种范式的所有优点(这不是问题的主题,所以我不会详述这个问题)。

然而,你不能忘记这样一个事实,即,在内心深处,运行代码的计算机或JVM,从根本上说是你必须提供改变内存状态的指令(你无法做到这一点)功能不足!)。

因此,出于性能原因,使用命令性元素有时会更好,但这应该以尽可能最受控制和封装的方式完成。这特别是标准scala库的情况,但在需要时也可能在任何开发人员代码的某些部分中使用。

一个很好的例子是在akka var中使用Actor。因为actor应该是并发计算的单个单元,所以它们可以具有一个内在的可变状态,这将由actor系统的原理封装(它表明你只能通过消息的方式与一个actor交谈),所以这种状态不会冒并发访问/突变的风险(在我看来,这是可变值的主要问题)。