Tuesday, May 3, 2011

The myths about the risks of introducing F# in your development team

At work we are a couple people who have been using F#. All people who have used it are enthusiastic, yet I was surprised today when I heard a project leader had asked to limit the use of F#.

There is a question on programmers' stack exchange which touches the subject titled "Real world pitfalls of introducing F# into a large codebase and engineering team". I'm quoting:
1) Everyone has to learn F#, and it's not as trivial as switching from, say, Java to C#. Team members that have not learned F# will be unable to work on F# parts of the codebase.
2) The pool of hireable F# programmers, as of now (Dec 2010) is non-existent. Search various software engineer resume databases for "F#", way less than 1% of resumes contain the keyword.
The fear is that maintaining F# code might be difficult because current employees and job applicants lack functional programming skills.

It seems some decision makers are still stuck at the time when C# 1.0, C++ and Java 2 were the languages of choice. Since then, a few things have happened.

Firstly, Python has become hugely popular. Although many were horrified by its use of white space to delimit blocks, it would be difficult to take seriously a programmer who claims he can't adjust to Python's syntax. Some love it, some hate it, but all can write Python code.
Why would the syntax of F# be any harder to adopt?

Secondly, C# has introduced a number of functional programming and other high-level concepts in each new version that has come out. Modern C# programmers are expected to master LINQ to objects, lambdas and yield return. The next version will introduce a specific syntax for asynchronous programming. Would you consider hiring a programmer would admits he knows nothing about these features and is unwilling to learn about them?
F#'s higher order functions, functions as first-class citizen, sequence expressions and asynchronous workflows match directly the modern features of C#. Why would these be harder to use in F# than in C#?

Dear reader, if you are a decision maker, I hope these two simple remarks dissipated your fears. You may be wondering why adopt F# when C# is evolving? You won't hear it from Microsoft, but the fact is that C# is breaking at the seams in its attempts to bring in new constructs. I won't give an exhaustive list, but here are a few examples of the limits of C#:
  1. Limits of iterator blocks (yield return). No such restriction in F#.
  2. Closures capture variables, not values. In F#, closures capture values, which is in my opinion a much saner design decision.
  3. Language-integrated queries are nice, but they don't sound as generic as they actually are. F#'s notion of quotation is more elegant, and makes it easier to see the applicability of LINQ beyond SQL.
  4. Although it's nice that C# is "stealing" async from F#, why not introduce the more general concept of custom workflows?
Moreover, F# supports a few data-types that somehow got forgotten when class-based OOP became dominant, namely records and discriminated unions. Together with pattern-matching, they are doing their come-back in the main stream and I have no doubt they will shortly become tools top programmers are expected to master.
 
Now, I'm not saying you should ditch C# and replace it "en masse" by F#. C# has better tooling support, features implicit conversions and a lighter syntax for implicit interface inheritance. I don't think these features are a must-have in all situations, but they can be handy at times.

Adopting all new hyped technologies has its dangers, but if you refrain from getting on with the times because of a few dinosaurs among your developers, your business will eventually go the way of the dinosaurs.

15 comments:

TechNeilogy said...

I can remember a long time ago pushing a development shop I worked at to adopt C++ and object-oriented programming in place of C. The resistance I met was so extreme that it bordered on personal insult. The rationale cited was pretty much the same as you described for F#: too few programmers use OOP and C++, we'd all have to learn something new, etc. Within a couple of years, however, it was a straight C++ shop. I'm not sanguine, but I hope the trajectory of F# is similar.

Carsten said...

I worked hard to be "allowed" to use C# instead of VB.net and as now the guys unwilling to learn something new have given up I had no problems with F# (just another .net language). But if I talk to some reasonal programmers why they didn't join the F# train I get some really good answers:
- Why? C# gives you (soon) all the good parts too.
- The tooling for C# (refactorings, project-handling, etc.) is so much better - are you kidding me?
- Why stop midway and not go all the way to Haskell instead?

The last 2 points are really good. The project-system is a pain in the A. and the F#-editor support is still buggy and has a long way to go where VS+say Rsharper is today.

And then Haskell ... ah - if I had a .net implentation of Haskell I would switch at once. Just the type classes and some nice litte thinks like "where" makes Haskell so much supreme, more readable and more powerfull than F# ....

And (hating to say this) I think in the long run MS will abandon F#. Hints for this are allready out there...

Fahad said...

@Carsten, Even if MS abandons F#, Except for the visual studio tooling, F# is so sound that in its 2.0 version it has far more features than C# 4.0.

-Fahad

Joh. said...

@Carsten: I would say tooling is a false problem. Start by getting the language right, then fix the tools. I'm a little disappointed that we haven't seen more productivity tools emerge as the F# compiler was made open-source, but hopefully that's just a matter of time.

Regarding the third point, I think the idea that Haskell is the king of functional programming languages is a misconception that is mostly present among people who are new to functional programming. If you think F# isn't "functional enough", you may want to go for some other ML variant.

In my opinion, Haskell's commitment to laziness and immutability confines it to the academia (which isn't a bad niche, after all).

Joh. said...

... and before I forget, where did you get the idea that Microsoft was going to abandon F#? Last week we saw they were looking for testers, and during early spring they advertised quite a few development and research positions.

Kannan said...

2. Closures capture variables, not values. In F#, closures capture values, which is in my opinion a much saner design decision.

Closing over variables is more expressive and more orthogonal.

The article you link to shows unintuitive behavior, but I think the real cause of that behavior is that the foreach loop scopes the loop variable incorrectly.

People expect the loop variable to be scoped to the body of the loop, but C# scopes it to the entire loop.

Barend Venter said...

@Joh
I understand what you wrote was in response to Carsten's post. Mind if I ignore that for this one? Sorry. I hope I've managed to trim this comment to a reasonable length.

From what I can tell from some google searches on programming language popularity, Haskell appears to have escaped academia better than OCaml, SML/NJ, and kin has. Note that LISP-likes generally are more popular and stuff like JavaScript absolutely dwarf the likes of Haskell or SML.

Thinking about it at first, it seemed obvious: Haskell has a lot of good tools and libraries, and a large and active community. Perhaps more so than F#, and definitely more so than OCaml or SML.

Then I realized that this presents something of a chicken and egg problem. I honestly have no idea how to take account of how it got started. I have some ideas, but I can't really articulate them well, and I want to keep this post short, so I'll only cover one!

I suspect syntax. Everyone likes nice syntax. Haskell has nice looking syntax by any standard, and it's regular too so it isn't hard to learn and even harder to unlearn. It's a bit simpler and cleaner looking than the MLs' (no fun, rec, val, less lets, no special syntax for mutual recursion like F# "and", etc) but otherwise very similar. Nice syntax can keep someone hooked until they learn to like the things they really should be liking. Is syntax enough on its own to launch yourself to success? Perhaps Python is a living example.

Either way, in response to someone saying that F# is not functional enough, it doesn't seem fair to say Haskell is confined to academia and then point to one of the more MLs instead. Not that I really think there should be any hating on F#. Nor on the MLs. Popularity does not count for everything.

Joh. said...

Barend Venter, as you point out, it does not really matter who among ML and Haskell is more popular outside of academia.

It is important however to understand what kind of restrictions you will impose on yourself when choosing. It is my personal opinion, but I could be wrong, that uncompromising purity and laziness are too limiting.

In any case, F# and Haskell are different enough that suggesting not to use F# because Haskell is available as a "better F#" is strange. The two languages belong to different branches. One is not an evolution of the other.

Finally, AFAIK there are no implementations of Haskell for the .NET platform, which discards it as an option for the kind of companies I am aiming at in my post.

Onur Gümüş said...

Why not use Nemerle instead of F# ? At least Nemerle has metaprogramming.

Joh. said...

Kannan, I disagree that capturing variables is more expressive than capturing values. Capturing a variable is simply achieved by using a wrapper object (ref in F#) and capturing the reference to that object.

I don't know what you mean by "more orthogonal".

Joh. said...

Onur: Yes, why not? I don't know much about Nemerle, so I can't comment. I could replace "F#" by any .NET programming language and half of the article would still apply.

TechNeilogy said...

The main selling points I've found for F# are the succinctness of the code, and ease of rapid development. I explain that the F# version uses only 10-25% of the source code of a C# version and that it only took me four days to write and debug instead of two weeks. I also point out that, yes, F# does have a steep learning curve, but though steep, that curve is *brief*. A few weeks at most for a dedicated individual, and for at least half of time, there has been enough progress to make working on real code possible.

Kannan said...

@Joh: By "more orthogonal" I guess I mean that code in a closure behaves like code not in a closure. It's nice when "EXPR" behaves the same way as "(fun () -> EXPR)()".

A closure captures the current environment and if the environment has bindings to variables, then I think the closure's environment should also have bindings to those variables (as opposed to copies of them).

A-Dubb said...

I'd definitely agree that F# is a great language and certainly worth learning. It'll teach you the fundamentals of programming and can actually help make you a much better developer when not only writing C#, but overall. Picking up on concepts like reactive programming, immutability, higher order functions, monads, etc. is just great. Developers get so caught up in "tools". No one wants to work with something pure because they want the help of an editor or designer. Don't let that get in the way of something great. That used to be the reason people preferred Entity Framework over NHibernate..."tooling". But guess what? NHibernate is still the defacto ORM showing up in all the latest books and Ruby on Rails is definitely still the leading web development framework (at least in my opinion). Why do I bring up Rails? Because people are just fine writing Rails apps with Vim and the command line. Not once do they ever mention tooling. They have an unconditional love for what they do. And that's all that matters. That you're using a sound framework that helps you do your job better and you "like" it. I'll bring up one more example. My former shop wouldn't adopt MVC despite it being far more superior than Web Forms? Why? Because they're weren't user controls to do the job for them. So what! Just learn HTML, the MVC pattern and be 3 times as productive while you're at it. So much love for F# and to those that realize its true power and elegance.

Joh. said...

A-Dubb: I think tool support is overrated as far as productivity productivity is concerned.

It is said that programmers spend 20% time writing programs, and 80% testing and debugging (I've also heard 50-50, I don't know if they are serious studies on the subject).

If that's true, and if refactoring is part of the programming phase, then refactoring tools and designers may not be as vital as we think.

However, as far as the programmer's comfort goes, it's hard to be without them when you have used them.