I still don’t get F#

I think that Microsoft are trying to sell F# to us as something new and awesome, but I’m having serious problems seeing the benefits over C#.

But F# can do function currying!
Well, so can C#.

string Foo(int a,bool b)
{
    //do stuff
}

void UseCurry()
{
  Func<int,string> curriedFooWithTrue = a => Foo(a,true);

     //invoke curried function.
  var res = curriedFooWithTrue(123);
}

F# can do pipelining!
Well, so can C#


var listOfInts = new List<int> {1,2,3,4,5,6};
Func<int,int> squared = x => x*x;
var squaredListOfInts = listOfInts.Select(x => squared).ToList();

F# can use tuples!
Well, they are built into .NET 4 as a generic type so they are available for all .NET languages with generics support.

F# can do tail recursion.

OK, you got me, it can.
Now let me know the last time you really needed that?
All tail recursive algorithms can be implemented as iterative.
But sure, syntactic sugar is nice to have.

F# makes it easier to write async code.

This was one of the arguments at a demo of F# at PDC 2008.
They showed how it was made possible by using PLinq wrapped up in a C# assembly.

Maybe I’ve misunderstood every example I’ve seen, but most of them can be done in C# with pretty much the same amount of code.

What I would like to see is a really good F# example that would be very hard or impossible to accomplish with C#.
If F# is just slightly better than C# on some tasks, then the cost of bringing F# competence into a project will always outweight the slight benefits it brings.

Another argument is that it targets a completely different problem area.
OK, show us where F# shines without lying about what C# can and can not do.

Anyone got such example?

29 thoughts on “I still don’t get F#”

    1. Several areas come to mind:
      1) Pattern Matching – useful in tree processing and languages – http://tomasp.net/blog/fsharp-iv-lang.aspx
      2) F# has immutable data structures – immutable data structures can be created in .net but in F# they are the default and the language runtime comes with immutable versions of the basics (lists, maps, etc)
      3) async programming – using workflows to to async programming is just so much easier than in C# – again you CAN do async programming in C# its just easier using async workflows in F# – Here is the one I am working through now – http://codebetter.com/blogs/matthew.podwysocki/archive/2009/08/31/f-first-class-events-async-workflows-events-part-i.aspx which is part of a larger series about how F# makes events first class members of the language (which is not true in C#)
      4) Quotations – very useful in language processing and other more dynamic areas.

      Like most languages i haven’t yet seen anything I CAN’T do in C# just a whole lot of things that would be very painful and take a lot of code to do the same in C#

  1. I think a lot of the reason that I switched to F# comes from two things:
    1. Certain patterns like async continuations look better in code in F# and its more readable. That said they first one I worked with was in C#
    2. Terse syntax. I feel like I am writing less code to get the same amount done. I also feel like I am spending more time working on my problem then gluing things together. I hate typing out types and think type inference at compile time is awesome.

    There are still some things that they could do to really differentiate like mixins. Hopefully they will.

    Also functional languages are used quite a bit in finance for modeling. There are situations in certain problem spaces where functional languages generate faster code than even c++ compilers due to certain optimizations for those problem types. They are simply a bit higher level and I believe in writing in the highest level language possible to solve a problem.

    A great example of something that you can do in c# but is incredibly painful is optimizing Abstract Syntax Trees and searching large trees to rewrite sub trees. Active patterns make this a fairly easy project. I might have nightmares about doing this in C#.

    All that said I work with a lot of problems that lend themselves to F#, complicated highly async algorithms, machine learning, expression tree optimization, etc… and I spend very little time on “normal” apps. I tend to still write UI’s and stuff in C# since the tooling is better. As always, right tool for the job.

    One good reason to learn F# as a C# developer is that it will teach you much quicker how to take advantage Linq and different fucntional patterns which will be more prevalent as time goes on.

  2. One more thing…Compile time checking of units is awesome. Not a major feature or even one that is very hard to implement but still very useful. I believe that C++ has a similar feature in Boost.

  3. Hi!

    I use C# and F# daily. C# has better intellisense, but F# code is shorter and easier to read.

    When in C# the complexity is to handle so much code in the ide (usually you have at least 5 files open and functionality and side-effects everywhere), F# complexity is to understand what your small syntax really makes and what the order of parameter-execution is.

    I like thinking more than ide-handling so I prefer F#, but not much.

    Both languages have many good things but also some bad. Here are my top annoying things in C#:

    1) Long and confusing type definitions.

    //Little code, much types:
    var MyList = new List<Tuple> {
    new Tuple(s1, e1),
    new Tuple(s2, e2)
    }

    //Easy function but non-advanced reader confused by type-definition:
    Func<List<Tuple>, int, bool> NotEmpty = (coll, i) => !string.IsNullOrEmpty(coll[i].Item1) && !string.IsNullOrEmpty(coll[i].Item2);

    2) I can’t make generic class T where T : new(parameters).
    I would like to use immutable classes to avoid side-effects and illegal object states.
    I would like to use read-only properties with constructor parameters and a lot of generics.

    For example:

    public class ConcreteType{
    public int I{get;private set;} //don’t mess with my I
    public ConcreteType(int i) {I = i;}
    }

    // and then somewehere, I can’t make this kind of function:
    var t = MakeNewDefault();

    //ugly fix, makes my class harder to use:
    var t = MakeNewDefault(k => new ConcreteType(0));

    I would say most annoying thing in F# currently is type-casts:

    //You can’t say let (i: Int16) = 0, you have to say:
    let (i: Int16) = Int16.Parse(“0”)

  4. Hi!
    Sorry, your blog-editor did cut html-like tags, I’ll try one more time:
    var t = MakeNewDefault (lt) ConcreteType (gt) ();

    //ugly fix, makes my class harder to use:
    var t = MakeNew (lt) ConcreteType (gt)(k => new ConcreteType(0));

    where (lt) and (gt) should be html-chars. :)
    So the C#-illegal definition would be something like:
    class MakeNew (lt) T (gt) where T : new(int)

  5. This argument of “I can do everything in language x, why should I learn a new language” is ridiculously closed minded. Yes C# and F# are Turing complete. Good find! You should probably skip learning Ruby as well.

    Btw Anders, a general purpose language can be functional.

  6. @Amanda

    If both languages targets the same platform, and support almost the same feature set, then what would you say is the benefit of it?

    I have yet to see an example where F# really shines and where the ROI for solving it with F# is higher than if the same problem was solved with C#.

    Give me an example that is not an naïve AST or a async webrequest.

  7. Type inference (on everything, not just methods)

    It lets you write things with hugely complex types without making it unreadable but with full type safety.

    It’s got a (very usable) REPL. They’re talking about adding one to c# in vHypotheticalNext but that would involve _removing_ and implicitly setting things to make it easier. c# really doesn’t like being twisted to a non OOP style (the class boiler plate is always there).

    You can express data manipulation in a vastly easier manner (even compared to Linq) since the compositional primitives are already present.

    immutable by default leads to much better programming in the small, it’s hard to screw things up.

    many OO releated things are more painful in f# but constructors which set a bunch of fields/properties are in fact much easier to express.

    The compiler generated boiler plate for composed types like discriminated unions (why have to write the proper equality, hashing and comparison operators/methods by hand when the compiler will do it better)

    You pay for some of these things, I hate having to have the fsi and fs files for exposed types but that is really what you need to do to allow full realtime type inference (the declaration/implementation bit anyway, they could be in the same file if they changed their compilation model somewhat).

  8. The stuff you can do with a match statement in F# would require tons and tons of C# code to replicate. The comparison isn’t even close.

    F# has automatic generalization. C# programmers half the time don’t know how to generalize.

    When you point me to the Active Pattern implementation in C#, then maybe you have a case.

    Lastly, defaults matter. Mutable by default in a world where the default is chosen 90% of the time means most C# code in the wild will be amazingly brittle compared to F#, where things are immutable by default and mutable will stick out like a sore thumb.

  9. The exact same argument could be made for why C# exists in the first place. You can do everything with Visual Basic that you can with C#, and it targets the same platform, why did Microsoft bother?

    I think in C#’s case, one would argue that C# would be readily accessible to the C++ and Java developers of the world, welcoming them to the .NET platform.

    Same goes for F#. You cannot deny that there is a large, robust community of functional programmers out there, most of whom make their livings doing something other than writing line of business apps and crud forms. Scientific programming, compiler research, and financial analysis pop immediately into mind. These developers have molded a significant body of knowledge and have great value in their selected areas of expertise. These developers are currently working primarily with Haskell, OCaml and the like. Haskell for one has a thriving community, but wouldn’t it be great to have a functional language that Haskell devs can feel comfortable with, and yet plays nice with the .NET platform? Enter F#.

    Why do we need these functional programming yahoos anyway (the closed minded C# dev might ask)? Well, there are whole new volumes of design patterns and algorithms that are staples for a functional programmer that seem alien to the typical C# developer. Linq for example – that’s the tip of the iceberg. The fact that it exists in C# is a harbinger. C# is growing in functional directions, F# is born functional.

    Therefore, one could argue that F# has more reason to exist in a universe of VB and C# than C# had to exist in a universe of just VB. Since there’s effectively nothing you can’t do in VB that you can in C#, but F# brings real marginal benefit, quotations and computational expressions to name just two.

    I am a full time C# developer and I make a good living solving difficult and interesting problems. I’ve never been paid to use F# or Haskell (yet), but surely those languages have helped be grow as a developer and a problem solver. After so many years of Object Oriented programming ruling the roost, I’m thrilled to see what used to be considered academic and even fringe ideas and thinking going mainstream.

    Thanks F# !!!

  10. Roger,

    Let me ask the question this way.

    C# doesn’t make Sense, what can C# do that MSIL can’t do? why do we need C#?

    Or for that matter any other Abstracted language above MSIL?

    Funny thing you fail to mention, Tuples were implemented at the BCL level because of Python and F#.

    We wouldn’t have the Generic implementation in the BCL if it wasn’t the work of Don Syme, the Creator of F#.

    Why doesn’t C# do tail recursion? it has been in the BCL since 2.0, improvements have been made in it’s structure with 4.0.

  11. Douglas
    >>C# doesn’t make Sense, what can C# do that MSIL can’t do? why do we need C#?

    C# let us write considerably less code than if we would write the same code in CIL.

    F# doesn’t let us write considerably les code than C#.
    It helps on some areas, but IMO, not enough give a better ROI than C# in most cases.

    >>Why doesn’t C# do tail recursion? it has been in the BCL since 2.0, improvements have been made in it’s structure with 4.0.

    Because you can write itterative algorithms that are easier for normal people to grasp than some recursive beast?

  12. Eric Vincent, I think you are misunderstanding me completely.

    I’m well aware that there are domain problems that F# solves much better than C#.
    But Microsoft markets F# as the new best thing, functional programming für alles.

    And in that aspect, it fails, far from everyone will need it.

    So what I’m saying is that I don’t get it from the perspective of the MS marketing hype.

    It isn’t for everyone, it doesn’t make life easier for the majority of developers.

    1. So you’re not asking “why does F# exist”, but rather, “why is Microsoft marketing F# as the new best thing”.

      First, I don’t see where F# is being marketed as the “new best thing”. Perhaps you should site examples. After browsing over msdn.microsoft.com/fsharp and msdn.microsoft.com/visualstudio, I didn’t see anything to support your claim. The titling on the F# page reads:

      “F# is a functional programming language for the .NET Framework. It combines the succinct, expressive, and compositional style of functional programming with the runtime, libraries, interoperability, and object model of .NET.”

      Pretty benign statement of fact that is.
      Not only am I not seeing your point, I’m starting to thing you’re trolling for … I don’t know what… traffic? attention? There’s no interesting debate happening here.

  13. But Microsoft markets F# as the new best thing, functional programming für alles.”

    never, ever has it done this.

    The people that wrote f# admit it’s abilities are better at ‘programming in the small’ rather than writing vast interlinked OO libraries (like say a widget toolkit) but that the in the small bits can be massively powerful and then trivially exposed in most cases to other more conventional .Net languages.

    You are putting words in their mouth, this is… disingenuous. You may have a point, but you must argue that point from some reasonable basis.

    I have seen *immensely* powerful and useful ‘scripts’ in f# with some decent backing functionality (mix of f# and c#) that utterly removes the need for previous use of statistical analysis toolkits like R/S+. They are faster, 64bit capable, debug-able with VS, much easier to tweak to how the team wants it.

    That most of the primary developers were trained in FP from university helps, but the people with no previous FP knowledge now using the system are vastly more productive.

  14. The entire post is about >>me not knowing/seeing where F# shines<<.

    That doesn't mean that I think F# is a horrible language, it means that what I've seen so far isn't that exciting.

    I explicitly asks for samples that can enlighten me.
    Read the bottom part of the post…

    My arguments are based on the samples that have been shown in public on F#.
    e.g. various async RSS readers and what not.
    Pretty much all of those samples can be done in C# with almost the same amount of code.

    1. I quoted your comment. (albeit your blog stripped the first quote)

      Your expectations seem way too high. There will be plenty of stuff of about the same effort, plenty much nicer in c# (bit manipulation, massively/heavily recursively dependent type hierarchies) and plenty much nicer in f#.

      Many of the examples given to you that really are much better in f# you haven’t acknowledged but the sort of people using them in finance aren’t going to just put the code online :)

      Another one you can’t ever approximate:

      Ever found the inability to express operators in generic constraints in c# a pain? take a look at ‘inline’ c# has nothing like it at all.

      That those things don’t matter to you (or to many LOB apps) is by the by. Not every one ids doing what you do.

  15. > “(ok, it’s not 100% clean)”

    it’s good that you independently came up with the MiscUtil stuff which is impressive, but it is nothing like the performance of inline, doesn’t play nice with mixing compatible types with coercion and doesn’t support other user types that provide operators
    Want your Complex struct to work for example? code it all yourself.

    > “I’m building DSL’s/compilers too, and I’m still not sold on F#.”

    Truly amazed.

    Try this in c#
    http://blogs.msdn.com/ashleyf/archive/2010/01/15/fscheme-0-0-0.aspx

  16. I think most of the comments here has answer your question quite elegantly. I just want to point out that by stating: I can do the same thing in C#, here is my library; you’ve already answered your own question. F# support all that out of the box because it’s a functional language. In fact your supporting library, assuming that it’s written correctly, is turning that part of C# into a functional language.

  17. The comments do answer the question, and I think the reason you pass them off is the point where you say F# is not significantly more concise than C#. It is.

    It allows your data and function definitions to take as few lines of code as they should be taking.

    Record and variant declarations, which are given on a single line usually, would correspond to one member per component and a class per constructor in C#. The LOC ratio is large, even more if you define redundant accessors and follow other ‘good style’ guidelines.

    Pipelining is something you can do about the same in C# (although the examples you’ve looked at have likely been simple), and this is thanks to additions inspired exactly by the paradigm F# is representing.

    The family of languages F# comes from is very old though, it could be less verbose. In a Haskell-like language, which is more to my preference, you could define your function as:
    squarelist = map (^2)
    It gets more fun with larger examples of course, such as where the name is not longer than the definition.

    To find computations where F# gets more concise you have to look at recursive algorithms, uses of the variant types and such. A function to insert a node into a binary tree might be 5 lines in F#, but 50 in C#.

    The code ends up being more horizontal, and your eyes stay on the same line more often when you’re reasoning instead of jumping around the page.

    You might not care much for all the line counting being used to C#, but compact code is certainly easier to navigate and manipulate rapidly.

    I recently wrote a physics engine in C#, and taking care to clean up and optimize all the code I took from, I ended up at under 1k lines, being fully featured. This should make the engine excellent for educational and customization purposes.
    If I’d written it in F# (it was my first use of .NET, so I somewhat needed IDE hand-holding), it might be even half that. How cool would that be.

    I also recently took a look at your SyntaxBox component, it was like 30k lines? After some problems and more browsing I decided I’d write my own renderer and parser, in F# this time; I don’t think it will be above 1k lines, with all the same features. That’s sort of my coding style.

    Ahh, cheers

  18. I agree that reducing the number of lines of code, while interesting, isn’t really a good selling-point for a functional language. I think it takes some time spent coding in a functional style to appreciate the real benefits, which are that for many problems, the functional style is a cleaner expression of the algorithm at hand, being more close to a pure mathematical solution, and that the state of the program can be managed better. For example, expressing the valid states of your program as algebraic data-types (ADTs), you can build up a program where *only* valid states can be represented. This is done with, for example, union types which always have to pattern-matched whenever they are used, and if any pattern-match is lacking a match case, then the compiler will warn that the match is non-exhaustive. Of course, this doesn’t prevent List.head from throwing an exception, but you could avoid using that function and perform pattern-matching on lists, as well.

    (Perhaps this applies slightly more to Haskell. I think coding in Haskell for a while makes it easier to understand what the “hype” is all about, whereas it may take some time to “get it” writing small code samples in F#.) I feel that coding in the functional style can also become a sort of “theorems for free” or applied intuitionistic logic (see the Howard-Curry Correspondence.) Every time you write a pure function which takes one type and returns another type, the signature of that function (in Haskell notation) reads just like implication in constructive-logic, and then, through proof-by-construction, your finished function body can act as a sort of “proof” that it was possible to transform from the input type to the output type. Though the beginner in F# won’t get this immediately, coding in the functional-style over time may lead to some intuition about how writing programs in that style is like writing proofs, in a non-formal way.

    I admit that I’m still struggling to see whether F# is good for FP in the large, as much as Haskell may be. Both Scala and F# are good for giving conventionally-trained programmers an easy entry into the paradigm (for some definition of easy; Scala is rather complex), but may not be as good as Haskell at FP in the large.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s