Thursday, January 26, 2012

F# vs. Scala, My Take at Year Two

I spent a lot of time over the last couple of years learning F#. Over the last six months, I’ve spent most of my time learning and working in Scala. During part of both those times, I was working on the same set of code, ported to both languages. So, though this topic has been covered before, I thought I’d add my few observations from that experience to the great F# vs. Scala debate.

1) From the standpoint of most programmers, the choice of F# vs. Scala is probably determined by a single external factor: whether one is targeting the .NET ecosystem or the Java ecosystem. So the real-world debate is less likely to be F# vs. Scala than it is to be F# vs. C# or Scala vs. Java.

2) If you know F#, you already know all the really hard stuff you need to know about Scala, and vice versa. Now I’m not saying there’s 100% overlap between the two languages; each has features and quirks that the other lacks. But if you’ve reasonably mastered either, you’ve already gotten into the functional/mixed paradigm mindset. You’ve scaled the cliffs of type inference, case classes, pattern matching, first-class functions, currying, continuations, monads, etc. To move from F# to Scala or vice versa, you may have to learn moderately different ways to express those ideas, but you don’t have to make the climb all over.

Now the more technical stuff:

3) F# syntax is austere and a clean break with the curly brace world, whereas Scala retains much of the curly brace look and feel (while significantly cleaning it up). This was a deliberate decision on the part of the designers of Scala to ease the transition from Java. The result depends on your viewpoint: F# code is a more succinct if you’re used to reading it, but Scala is a little friendlier for newcomers.

4) Both languages are multi-paradigm, but F# favors functional programming whereas Scala favors object-oriented programming. This is not intended as a comment on the capabilities of the two languages, but rather on the “feel.” Both are clearly multi-paradigm, it’s just that on an FP to OOP scale of 0 – 9, F# feels more like a 4, and Scala feels more like a 6.

5) Scala programming rests on a foundation of traits, mixins, and the explicit management of types. Programmers making either the transition Java -> Scala, or C# -> F# -> Scala, will need to spend time mastering these concepts in order to take full advantage of Scala’s capabilities. (F# programmers from more academic backgrounds will already be more familiar with these things.)

6) F#’s higher-order libraries feel a little more pragmatic than do Scala’s. It’s not that you can do something in F# that you can’t do in Scala, it’s just that I’m often able to find a more precise higher-ordered function quicker in the F# documentation than in the Scala documentation. (To be fair to Scala, the libraries are evolving, and tend to get cleaner in each version.)

7) If you’re a .NET programmer without much open-source experience, getting started using Scala is likely to be both terrifying and exhilarating. What I mean is: if you do .NET programming, you have Visual Studio, and if you have Visual Studio, you have F#, and the F# you have just works – there, out-of-the box, batteries included. To do Scala, on the other hand, you’re going to have to put together a toolkit for yourself, sometimes pulling resources from various open-source concerns. But there are a couple of pieces of good news to temper this: first, Scala is much easier in this regard than much open-source software I’ve encountered; second, the inventors of Scala have started a concern called Typesafe to help centralize these resources (see sidebar links under Scala).

8) The community experience is excellent in both cases. Both the F# and the Scala communities are filled with excellent programmers who are passionate about the discipline. The users and committers of the two languages are their greatest assets.

I’ll end with two metaphors, the first about F# and Scala themselves, and the second about the two communities:

F# and Scala remind me of the cases of convergent evolution in the biological world. They have evolved in different ecosystems, but similar selection pressure has resulted in similar outcomes. And some of those pressures are among the most important in all of computing: correctness, concurrency, distributed computing, and maintainability.

And lastly, the F# and Scala communities are less like two rival groups of barbarians storming the same castle than they are like one group of barbarians temporarily divided so they can storm two different castles. (And storm them for their own good, lol.)

-Neil

26 comments:

Anonymous said...

very nice description of how these two languages relate and complement each other

TechNeilogy said...

Thanks! I wanted to emphasize that F# and Scala are not so much competitors as they are cousins. In many cases, the choice of .NET vs. Scala is out of the hands of the programmer. However, F# and Scala complement each other so well, that programmers can gain leverage by learning and applying both as the premier mixed paradigm languages in each realm.

Anonymous said...

Neat article and I tend to agree with most of what you said. On the downside, I don't see the point in the comparison of getting started with F# vs. getting started with Scala. In fact, I'd like to throw that stone back by asking if it's not way more time consuming and more hassles to get Visual Studio installed (as well as all the rest that comes with it) than just downloading the "default" Scala stack from typesafe? Also, the Scala plugins for IntelliJ or even more the one for Eclipse are just delightful. That being said, the rest was a nice read.

TechNeilogy said...

Thanks! That's a fair comment; I should have been more clear. My point was that getting started with open source tools was a challenge for me specifically because it was a different way of doing things than I was used to. I "grew up" with Visual Studio, and so it feels like second nature to me. For a person used to open source tools and coming to Visual Studio, the shoe would, of course, be on the other foot.

TechNeilogy said...

p.s. That comment also reminds me: I should have given a shout out to the folks at JetBrains; choosing between Eclipse and IntelliJ is like picking the first among equals. (.NET programmers will be familiar with JetBrains through their ReSharper product.)

Anonymous said...

Nemerle is better than both

Unknown said...

Interesting comparison. I chose F# over scala because it hides, or supresses, much of what I consider complex about Scala. The syntax feels far simpler and extension methods feel far easier (and less dangerous) than Scala implicits.

Then there are F# builders - very nice. I enjoy the async stuff, and you can easily build actors out of it.

I'm interested in your comment that OO isn't supported well in F#. What parts do you feel are missing? I've found F# to be a nicer OO language than C# (despite missing support for partial classes). The only thing it is potentially missing is Scala traits/mixins and even then I'm not sure it's such a big deal...

Andrew

Unknown said...

> In fact, I'd like to throw that stone back by asking if
> it's not way more time consuming and more hassles to get Visual Studio installed
> (as well as all the rest that comes with it)

Nah, it's easy. I'm an eclipse fan, but the visual studio install is scarily simple.

You can get a fully featured F# IDE for free - download the VS2010 shell, install it, and then install the F# community release. Full integration just like that. Took me 10 minutes. And it has no C#/VB baggage.

Plus the free VS shell has the WPF designer built in.

TechNeilogy said...

"I'm interested in your comment that OO isn't supported well in F#. What parts do you feel are missing?"

I was thinking more in terms of "flavor" than of capabilities. F# and Scala are both multiparadigm languages, and both support OOP very well, but in F# the functional aspects show through more clearly to the surface and syntax of the language, whereas in Scala, it's the other way around. But it's a 60/40 thing; squint at each language one way and it looks FP, look a few degrees to the other side and it looks OOP.

TechNeilogy said...

"Nemerle is better than both..."

I'm working my way around to it, lol.

Unknown said...

> Nemerle is better than both

care to substantiate? I'm interested to know what features are missing from F# in particular.

Andrew

Anonymous said...

IMO if you search a more simalar language to F# than scala for the JVM than you should take a look at yeti ( http://mth.github.com/yeti/).

It is a statically typed ML style functional programming language, with full HM typeinference. While functional is also more prominent like in F# OO can be done using structs.

missingfaktor said...

"F# code is a more succinct if you’re used to reading it, but Scala is a little friendlier for newcomers."

F# code if anything is usually way more verbose than Scala code. Scala code has more type annotations than corresponding F# code, and declaring things like ADTs is more verbose. But at the same time, Scala has got much more powerful type system, and that facilitates design of better, more general abstractions, reducing code duplication to a great extent, and making user code very terse. I am talking about features like type classes and type constructor polymorphism, both unavailable in F#.

missingfaktor said...

"Both languages are multi-paradigm, but F# favors functional programming whereas Scala favors object-oriented programming."

I am tired of hearing this one. Can you elaborate on why you think so? Can you name a functional feature that Scala does not have and F# does? On the contrary, Scala does support a few functional features that F# doesn't. It's not possible to write even a monad interface in F#. So I find the claim that F# is somehow more amenable to functional programming as compared to Scala laughable.

I have been using Scala for more than 2 years, 7 months professionally, and my code is mostly purely functional, and makes use of abstractions which are not expressible in F#.

missingfaktor said...

"F#’s higher-order libraries feel a little more pragmatic than do Scala’s. It’s not that you can do something in F# that you can’t do in Scala, it’s just that I’m often able to find a more precise higher-ordered function quicker in the F# documentation than in the Scala documentation."

Can you give a few examples to support your point? I have an exact opposite opinion on this one. Especially in case of collections. F#'s lacks most common higher order functions (common in Haskell and Scala I mean), and so one ends up writing more code, and has to resort to recursion more often than one might like. In Scala, like Haskell, higher order functions get job done most of the time.

Please do not misunderstand me. This was a good post, but seemed a bit biased on F#'s side, and appears to have some technical inaccuracies, and so I thought I should point them out.

TechNeilogy said...

@missingfaktor

First off, thanks for all your comments! We may disagree in places, but you make your case well. If I seem slightly biased in favor of F#, it’s probably a product of my longer experience with F# and .NET than with Scala and the Java ecosystem.

I want to reiterate that my purpose was not to pit F# against Scala. Generally, the decision of ecosystem is made first, and then the programming language is chosen. What I wanted to do was to explain to F# programmers who find a need to work in the Java ecosystem that Scala is an excellent and natural choice. And vice versa for Scala programmers who find a need to work in .NET. I wanted to explain my experience of that process in the F# to Scala direction.

But it was inevitable in the process that I would end up comparing the two languages, and your points are well taken.

TechNeilogy said...

@missingfaktor re: OOP vs. FP

As I mentioned in an earlier reply, my comment about OOP vs. FP was not directed at the technical capabilities. These are roughly equivalent, or even – as you point out – stacked slightly in favor of Scala.
It was just an opinion about how the two languages “feel” to me as I’m using them, not an absolute value judgment.

This feeling is as much about syntax and expected use of the language as it is about capabilities. F# feels like what I would expect if you locked three Haskell programmers and two Java programmers in a room and asked them to sketch out a language. Scala feels like what I would expect from three Java programmers and two Haskell programmers. Even for me, it’s a 60/40 thing, it’s perfectly reasonable that others may see things differently.

I’m no mind reader, but this desire to create an OOP “feeling” seems deliberate on the part of the designers of Scala. It’s a perfectly reasonable tactic given the target audience of Java shops. Get them hooked by showing them familiar OOP code, then show them how much farther they can go using FP.

TechNeilogy said...

@missingfaktor re: higher-order functions

In this last, I think we are arguing from the same premise: that a larger collection of higher order functions is available in Scala, and more are defined as operators. The F# collection is more pared-down and austere. This may make it easier for a beginner to find things, even if a few expert tools are lacking that could shorten the code. Not a major sticking point in the usability of either language, just a subjective opinion from someone who relies a lot on code completion (relies too heavily, I sometimes fear).

And thanks again for commenting.

Anonymous said...

Since JetBrains brought aboard some of the Nemerle developers, I'm hoping that VS will get a killer Nemerle addin.

Nemerle has macros, so in theory it doesn't need so much stuff baked into the language like F#.

As the angry Scala "enthusiast" pointed out, there are some constructs that Scala has that are impossible in F#.

It really doesn't matter though. I'd bet on Kotlin "winning out" in the long run over Scala for various reasons.

There's just too many problems with tooling and compilation speed in the Scala world that never get worked out.

missingfaktor said...

Anonymous, don't be a dick (referring to your remarks - enthusiast in quotes and angry). The rest of your comment was informative though. So thanks.

TechNeilogy said...

I used to be an "editor and make" type, but a decade+ of good IDEs is making me soft. And the JetBrains guys are (IMHO) building the Cadillacs of IDE world.

I'm always in favor of more language options. Nemerle and Kotlin have been on my radar screen, but so far, I've only read about them and not actually used them.

Scala is a wonderful language, and I love it – I've spent much of the last year since the original post using it professionally. I just finished some analytics work in Scala.

But I do think the lack of turn-key tooling is killing Scala a bit in the Java world. Most Scala enthusiasts are willing to tinker; busy Java programmers need as simple a way to try Scala as VS provides for F#. Scala needs to be right there, ready to go, ready to fill up that awkward ten minutes before lunch.

TechNeilogy said...

Play nice, you all!

Sebastian said...

Very nice comparison.

Could you comment on how well each integrates with the "lingua franca" in their respective runtimes? (how well F# integrates with existing C# code/libraries, vs. how well Scala integrates with existing Java code/libraries)

About Nemerle: what's its status? I thought it was no longer being actively developed. I might be wrong though.

Chris St. John said...

Great post. I'm a .NET veteran myself, just learning F# and learning to embrace its functional style. I now face a possible career change over to the Java ecosystem with trepidation; the existence of Scala definitely makes the move more palatable.

TechNeilogy said...

Thanks Chris. That mirrors my own experience. I faced a choice of porting either a C# version of our software to Java, or of porting an experimental F# version to Scala. I choose the latter, and have never regretted it.

Chris St. John said...

> porting ... a C# version of our software to Java

Wow, I can only imagine how painful this would be without any functional constructs in Java, especially if you make heavy use of the Linq Enumerable extensions.

I also agree with your comment that JetBrains are making the Cadillacs of IDEs. My brief foray back into the Java world using Eclipse felt like walking on hot coals: with missing language features and missing IDE features it's possible to get there, but every step is unnecessarily painful. IntelliJ at least made me step back from the proverbial ledge. I shall have to try out its Scala support.