Having now worked a fair amount with Scala, I can now unequivocally make this assertion:
Scala is not a functional programming language. It is a statically typed object oriented language with closures.
So, I’d appreciate it if people would stop the bogus sales pitch.
To understand the distinction, take a look at this surprisingly interesting troll from Jon Harrop on the Scala mailing list. In that thread, Martin O. puts out a challenge, and claimed that OO solutions were the only “clean” one. One clean SML solution later, there was some refinement of the claim, that being that OO solutions were the cleanest ones when you had to replace your application’s core data structure many times. Ultimately, the conversation got bogged down in pedantic points about the particular challenge, but it was fascinating when it lasted.
The key interesting point I walked away with was this quote from Martin O.:
An implementation of an abstract {def, val, type} can refer to other members of its superclass. But an argument to a higher order method or functor cannot refer to the result of the application. So open recursion with abstraction is supported in OOP but it requires elaborate and rather tedious boilerplate in FP (such as the encodings of classes in TAPL).
Now, this statement is kinda silly — as defined in Pierce, “open recursion” is an implicitly OO concept, so of course the FP languages have pain when you try to code them in a different paradigm. The question is whether that technique is necessary or even worthwhile in functional programming: does functional programming have an easy way to solve the same problems, or is it limited because it cannot pull this stunt?
So, when considering whether Scala is a functional programming language, let’s ask ourselves: how does Scala solve problems? Brian Hurt is fond of saying that when it comes to the nature of the language, it’s not about what the language makes possible, it’s what the language makes easy*. What does Scala make easy?
* Notably Martin O. seems to disagree: “The first thing we cared about was to have as clean an integration of functional and object-oriented programming as possible. We wanted to have first-class functions in there, function literals, closures. We also wanted to have the other attributes of functional programming, such as types, generics, pattern matching. And we wanted to integrate the functional and object-oriented parts in a cleaner way than what we were able to achieve before with the Pizza language. That was something we deeply cared about from the start. Later on, we discovered that this was actually very easy, because functional languages have a fixed set of features. ” (cite) — so, according to that thinking, if you hit the items on the check list, you’re a functional programming language. More on this later.
Let’s start with the basics: in a functional programming language, you program functions. That is, the solution is to encode the problem as function application. In OCaml, we define a function like this:
let f x = x + 1;;
In Scala, though, we define the function somewhat differently:
object SomeHolderObject { val f(x:int):int = { x + 1 } }
In OCaml, functions are defined directly — in Scala, we have to give an objective context to the function. Using the “object” keyword gives us a singleton object that we act against, but that’s no more functional an approach than the static context used by Java. So, at its fundamental organizational structure, Scala betrays its purportedly functional nature to be more object oriented.
Now, let’s consider where the abstraction lies in Scala. In Scala, the key way to abstract things is to implement partial contracts, either in the forms of interfaces or traits. Traits are the implementation of open recursion in Scala, which (despite its name) is precisely an OO feature! So now we’ve got Scala’s basic organization being objective, and Scala’s source of abstraction power being objective. 0 for 2.
For the shut-out, let’s see in Scala makes functional programming easy. Let’s start with my favorite functional language stunt: currying.
OCaml, you’re up to bat first.
let x a b = a + b;; let y = x 1;; y 2;; (* 3 *)
Not too shabby. Scala, show your stuff!
def x(a:Int, b:Int) = a + b def y = x(1) /* ERK! FAIL! <console>:5: error: wrong number of arguments for method x: (Int,Int)Int def y = x(1) ^ */
Want to try that again?
def x(a:Int, b:Int) = a + b def y = Function.curried(x _)(1) y(2) // 3
So, currying is possible, but not exactly easy (or pretty) compared to a real functional language. Okay, well, that’s fine. A bit of ugliness is minor: let’s try something more basic and fundamental to the algebraic functional programming paradigm.
What about Algebraic Data Types, common to functional languages — including my beloved OCaml variant types? They provide a key power behind pattern matching and static typing in OCaml/F# and Haskell — how does Scala fair?
Well, in OCaml, I’d write this:
type robert = Foo of int | Bar of string | Baz;;
In Scala, we get this:
sealed abstract class Robert; sealed case class Foo(value:Int) extends Robert; sealed case class Bar(value:String) extends Robert; sealed case class Baz extends Robert;
Oh, ugh. For a while there, I thought that noise was kinda-sorta justified because it allowed for case class inheritance — but that feature’s being driven from the codebase (more on that here). So it’s just plain noisy compared to the OCaml version.
This blog post could go on like this for a while, but I’ll invoke a mercy rule and simply say: Is Scala making functional programming idioms easy? No. 0 for 3.
So, what lead to the claim that Scala was a functional language is the first place? First-level functions? Perl, Ruby, and Groovy have those, and they’re not being called “functional languages”. Statically typed closures? C#. Matching? Easy to do in an OO style (cite), and largely wasted without easy algebraic data types. A penchant for immutability? That’s a good start, but is far from sufficient to make it a functional programming language.
No, Scala is not a functional language, because it doesn’t make functional programming easy. It makes it possible, and so the language certainly has functional accents, but Scala is not a functional language at its core. OCaml makes object oriented programming possible, and so the language has object accents, but OCaml is not an object-oriented language at its core. And that’s okay — but let’s call a spade a spade.
And don’t get me wrong: as a JVM language, Scala is a huge step forward. C# has so far outstripped Java as a language that it’s downright embarrassing, and Scala leapfrogs ahead of C# to put the JVM back in the lead. But Scala is first and foremost an object oriented language, so can we stop calling it a “functional programming language”? It’s deceptive, and it’s degrading what it means to be a functional programming language.
Related posts:
Pingback: David R. MacIver » Blog Archive » A problem of language
Pingback: Scala articles and news roundup: year 2009 – week 20 « The Lazy Dev
Pingback: WebDevGeekly » Blog Archive » Episode 14
Pingback: Web Dev Geekly #14 | Enfranchised Mind
Pingback: Enfranchised Mind » Anything Anyone Wants to Hear from Me?
Pingback: Enfranchised Mind » What is a functional programming language?
Pingback: Fragments forthcoming « Doug Milam
Pingback: Postfunctional programming language « techscouting through the news
Pingback: Scala: Post-Functional, Post-Modern, or Just Perl++?
Pingback: Functional Scala: Introduction « brain driven development