Friday, May 15, 2009

Erlang is Not Functional

Robert Fischer claims Scala is not a functional language. But if you go by his post then Erlang isn't either.

Modules

Fischer says

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 }
}

Now some Erlang

-module(SomeHolderModule).
-export([f/1]).

f(X) -> X + 1.

Erlang requires a function to be defined in a module. Scala calls a module an "object."

Currying and Partial Application

Fischer says [1]

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)
               ^
*/

And here it is in Erlang

- module(test).
- export([f/2]).

f(X,Y) -> X + Y.

1> c(test).
{ok,test}
2> test:f(1).
** exception error: undefined function test:f/1

Algebraic Data Types

What about Algebraic Data Types, common to functional languages - including my beloved OCaml variant types?

Erlang doesn't have them. You can fake them with tuples and atoms and such, but they just aren't part of Erlang.

Conclusion

Clearly, by Fischer's definition, Erlang is not a functional language.

But that's ridiculous.

David MacIver has an excellent post suggesting that there's a problem of language. Fischer hasn't defined what he means by "functional language" other than "feelings" so we're left with something nebulous.

I think MacIver is right, but Fischer does seem to have an informal definition. His definition of "functional language" is "OCaml". His post compares Scala to OCaml and concludes that because Scala is not OCaml Scala must not be functional.

Yet if I take his specific points I can find other functional languages, like Erlang, that are not OCaml either and therefor not functional either.

In fact, if I look at Common Lisp, Scheme, Clojure and Arc I find that they violate most of his demands too. So the whole Lisp family isn't functional either.

Fischer has fallen prey to a common mistake. He's overgeneralized from one datapoint. It's as if a Scheme programmer concluded that OCaml isn't functional because it doesn't have hygienic macros or a Java programmer concluded that Ruby isn't object oriented because it doesn't have inner classes.

Footnotes

[1] Actually, you can write "def f(a:Int)(b:Int) = a + b" in Scala if you want a curried function or you can write "val y = f(1, _)" if you want to partially apply an uncurried function. So Fischer blows major points here.