Scala是函数式编程语言吗?

21 投票
3 回答
16098 浏览
提问于 2025-04-16 18:33

我最开始学编程是从Java开始的,然后每年尝试学习一种新的编程语言,第二种是C++,接着是Python。当我准备学习下一种语言时,我想找点新鲜的,于是选择了Scala,因为它和Java兼容,可以帮助我从面向对象编程(OOP)过渡到函数式编程。

学习新的编程范式、新的风格和新的思维方式真的很酷。阅读优雅的Scala概念让我感到很棒,实际用Scala编程更是让我觉得很享受。

在阅读了很多文章后,我遇到了一篇批评Scala的文章

Scala并不是一种函数式编程语言。它是一种静态类型的面向对象语言,带有闭包。

看完这篇文章后,我心里开始有些疑惑。我真的很喜欢Scala,并且开始更多地用Scala编写代码,但Scala是否符合函数式编程的定义呢?那篇文章说的是真的吗,还是在误导读者?我是否需要学习Haskell或其他函数式编程语言,才能真正体验到函数式编程的魅力?

更新:希望能得到理性的回答,带有好的例子,不要引发争论。

3 个回答

19

我个人判断一个函数式编程语言好坏的标准就是教堂数字。

这里有个Scheme的例子:

(define (thrice f)
    (lambda (x)
        (f (f (f x))))))

((thrice 1+) 0)
  => 3

(1+ 是一个Scheme函数,它的作用是给它的参数加1。thrice 是一个函数,它接收一个函数f,并返回一个将f自己调用三次的新函数。所以 (thrice 1+) 就是给它的参数加3。)

((thrice (thrice 1+)) 0)
  => 9

(因为 (thrice 1+) 是一个加3的函数,如果再对它使用一次 thrice,就会得到一个加9的函数。)

还有我最喜欢的例子:

(((thrice thrice) 1+) 0)
  => 27

(推理留给读者自己思考。这个最后的例子是最重要的。)

如果你不能在你的语言中写出这个例子,而且写起来非常别扭,那我就认为这不是一个函数式语言(比如:C/C++)。

如果你能在你的语言中写出这个例子,但看起来非常不自然,那我就认为你的语言“支持函数式编程”,但实际上并不是真正的函数式语言(比如:Perl)。

如果这个例子能很顺利地移植到你的语言中,并且看起来和你平时使用的方式差不多,那它就是一个函数式语言。

我不太了解Scala。有人想告诉我它属于哪一类吗?:-)

21

Scala是一种多范式的编程语言,旨在结合面向对象编程和函数式编程的特点。

我也说不出更好的了,除了无谓的争论,没什么好再说的。

39

Scala并不强制你使用函数式编程风格。下面这段代码在Scala中是完全有效的:

var i = 1
while (i < 10) {
  println("I like side effects, this is number "+i)
  i += 1
}
case class C(var i: Int, var set: Boolean = false)
def setMe(c: C) = { if (!c.set) { c.set = true; c.i += 1 }; c }
setMe(C(5))

所以从这个角度来看,哎呀,Scala其实并不是函数式的!它有很多副作用,还有可变状态——你在Java中能做的事情,在Scala中也都能做到。

不过,Scala允许你使用函数式编程风格,并且在很多方面让你的生活比在Java中更轻松:

  • 它有一等公民的函数
  • 有不可变的集合库
  • 支持尾递归(只要JVM能处理)
  • 支持模式匹配
  • (等等)

下面这段代码看起来更像是函数式编程:

for (i <- 1 to 10) println("Sometimes side effects are a necessary evil; this is number"+i)
case class C(i: Int, set: Boolean = false)
def setIt(c: C, f: Int=>Int) = C(f(c.i), true)
setIt(C(5), _+1)

值得注意的是,写这篇文章的作者似乎对Scala的理解很浅薄;他手里的每个例子看起来都很丑,其实都是不必要的丑。例如,他写道:

def x(a: Int, b: Int) = a + b
def y = Function.curried(x _)(1)

但如果你认真对待你正在做的事情,其实没那么糟糕:

def x(a: Int)(b: Int) = a + b
val y = x(1) _

总之,Scala并不是一种纯粹的函数式编程语言,因此它的语法并不总是最适合函数式编程,因为还有其他因素需要考虑。不过,它几乎具备了函数式编程语言所期待的所有标准特性。

撰写回答