216

Over the last few years F# has evolved into one of Microsoft's fully supported languages employing many ideas incubated in OCaml, ML and Haskell.

Over the last several years C# has extended its general purpose features by introducing more and more functional language features: LINQ (list comprehension), Lambdas, Closures, Anonymous Delegates and more...

Given C#'s adoption of these functional features and F#'s taxonomy as an impure functional language (it allows YOU to access framework libraries or change shared state when a function is called if you want to) there is a strong similarity between the two languages although each has its own polar opposite primary emphasis.

I'm interested in any successful models employing these two languages in your production polyglot programs and also the areas within production software (web apps, client apps, server apps) you have written in F# in the past year or so that you would previously have written in C#.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Peter McG
  • 18,857
  • 8
  • 45
  • 53

9 Answers9

267

I have written an application to balance the national power generation schedule for a portfolio of power stations to a trading position for an energy company. The client and server components were in C# but the calculation engine was written in F#.

The use of F# to address the complexity at the heart of this application clearly demonstrates a sweet spot for the language within enterprise software, namely algorithmically complex analysis of large data sets. My experience has been a very positive one. In particular:

Units of measure The industry I work in is littered with units. The equations I implemented (often of a geometric nature) dealt with units of time, power and energy. Having the type system verify the correctness of the units of the inputs and outputs of functions is a huge time saver, both in terms of testing and reading/understanding the code. It eradicates a whole class of errors that previous systems were prone to.

Exploratory programming Working with script files and the REPL (F# Interactive) allowed me to explore the solution space more effectively before committing to an implementation than the more traditional edit/compile/run/test loop. It is a very natural way for a programmer to build their understanding of the problem and the design tensions in play.

Unit testing Code written using non-side effecting functions and immutable data structures is a joy to test. There are no complex time-dependent interactions to screw things up or large sets of dependencies to be mocked.

Interoperation I defined the interface to the calculation engine in C# and implemented the calculation in F#. The calculation engine could then be injected into any C# module that needed to use it without any concerns at all about interoperability. Seamless. The C# programmer need never know.

Code reduction Much of the data fed into the calculation engine was in the form of vectors and matrices. Higher order functions eat these for breakfast with minimal fuss, minimal code. Beautiful.

Lack of bugs Functional programming can feel strange. I can be working on an algorithm, trying hard to get the code to pass the type checker but once the type checker is satisfied thats it, it works. Its almost binary, either it wont compile or its correct. Weird edge case errors are minimised, recursion and higher order functions remove a lot of book-keeping code that introduces edge case errors.

Parallelism The functional purity of the resulting implementation makes it ripe for exploiting the inherent parallelism in processing vectors of data. Maybe this is where I will go next now that .NET 4 is out.

simon cousins
  • 101
  • 1
  • 3
  • 6
  • 21
    +1 for explaining why F# is very suited for number crunching engines. Another (virtual) +1 for mentioning units of measure. That part of the language deserves getting mentioned more often. – cfern May 07 '10 at 11:20
  • 5
    Great answer, relevant, contemporary and outlines F# suitability for dealing with complexity, I learnt a lot from reading it, thanks – Peter McG May 08 '10 at 05:58
  • Great answer Simon, and as Don mentioned last night, quoted in his recent slides. Time to add an "add to cart" link? – Chris Ballard Jun 24 '10 at 12:08
  • 1
    hi, are you allowed to tell us more about your apps architecture? – Nikos Dec 18 '12 at 02:26
79

During my internship at Microsoft Research, I worked on some parts of Visual Studio IntelliSense for F# (which is itself written in F#). I already had some experience with IntelliSense from earlier C# projects, so I think I can compare the two.

  • Visual Studio Extensibility is still based on COM, so you need to deal with objects that are not very nice .NET objects (and definitely not functional), but I don't feel there is any major difference between C# and F# (it works smoothly from F#)

  • The data structures used to represent program code in F# are mostly discriminated unions (which are not supported in C# in any reasonable way) and this makes a huge difference for this kind of application (where you need to process tree structures, such as program code). Discriminated unions and pattern matching allows you to structure the code better (keep related functionality in one place rather than having it all over the place in virtual methods)

Earlier, I also worked on CodeDOM provider for F# (also written in F#). I actually did first experiments in C#, but then converted the code to F#.

  • CodeDOM provider needs to traverse some structure represented using .NET objects, so there isn't much space for inventing your own representations of data (which is the area where F# can offer nice benefits).

  • However, there were many small F# features that made the task easier. Since you need to produce a string, I defined custom operators for building strings (using StringBuilder) and implemented the code using them and higher-order functions (e.g. to format list of objects separated using the specified string etc.), which removed a lot of repetition (and tedious foreach loops).

These are two relatively specific examples, but both of them are related to working with representations of programs, or expressions, or more generally, complex tree-like data structures. I think that in this area, F# is definitely a good choice (regardless of the functional features in C#).

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • 7
    Very interesting, more evidence that the uptake of F# within Microsoft is certainly high, what a great internship that must have been! – Peter McG May 06 '10 at 23:46
47

We shipped the world's first commercial product written in F# (F# for Visualization) and the second (F# for Numerics) as well as the first commercial literature on F# (The F#.NET Journal) and wrote and publish the only book about the current version of F# (Visual F# 2010 for Technical Computing).

We had been shipping products along similar lines written in C# (e.g. this) but we also had a strong background in the commercial use of OCaml. We were enthusiastic early adopters of F# when it was still a research prototype back in 2006 because we recognised the potential of having a decent modern OCaml-like language on the industrial-strength .NET platform and, consequently, we pushed to have it productized. The result has been an incredible success and F# has far exceeded our lofty expectations.

For us, F# has many different advantages and we use it for a wide variety of applications. We have hundreds of thousands of lines of F# code in production. We now use F# for all of our LOB apps: our credit card transactions are processed using F# code, our product notifications are sent using F# code, our subscriptions are handled using F# code, our accounts are done using F# code and so on. Perhaps the main language feature that pays dividends here is pattern matching. We even used F# to color syntax highlight our latest book...

Our visualization library is a big seller and its functionality centers on F# interactive running in Visual Studio. Our library augments this with the ability to spawn interactive 2D and 3D visualizations with minimal effort (e.g. just Plot([Function sin], (-6., 6.)) to plot a sine wave). In particular, all threading issues are completely automated so users do not have to worry about UI threads and dispatch. First-class functions and laziness were extremely valuable when writing this part of the library and algebraic datatypes were used extensively elsewhere. Predictable performance also proved to be valuable here when our customers hit performance bugs in WPF's hit testing and were easily able to reimplement the relevant code in F# for a 10,000× performance improvement. Due to the free-form nature of this product's GUI, the GUI designer and C# would not have been beneficial.

Much of our work revolves around numerical methods, including both our commercial libraries and books. F# is much stronger in this area than C# because it offers high-level abstractions (e.g. higher-order functions) with minimal performance penalties. Our most compelling result in this context was the creation of a simple but generalized implementation of QR decomposition from linear algebra that was 20× shorter than the Fortran code from the reference implementation of LAPACK, up to 3× faster than the vendor-tuned Intel Math Kernel Library and more generic because our code can handle matrices of any type, even symbolic matrices!

We are currently developing WPF/Silverlight components in a mix of F# (for the guts) and C# (for the shim), building WPF apps to act as interactive manuals for our software products and I am writing a new book, Multicore F#, that will be the definitive guide to shared-memory parallel programming on .NET.

J D
  • 48,105
  • 13
  • 171
  • 274
27

Over the last 6 or so months, I've been working on a Vim emulation layer for Visual Studio 2010. It's a free product with all of the source it's freely available on github

The project is divide into 3 DLL's representing a distinct layer. Each layer has a corresponding unit test dll.

  1. Vim Engine: F#
  2. WPF layer for adornments and editor integration: C#
  3. Visual Studio Integration layer: C#

This is the first major project I've ever done with F# and I have to say I love the language. In many ways I used this project as a method of learning F# (and this learning curve is very much evident if you look through the history of the project).

What I find the most amazing about F# is just how concise of a language it is. The Vim engine comprises the bulk of the logic yet it only comprises 30% of the overall code base.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 19
    Editor ... functional language ... vi emulation ... you've re-invented emacs. NOOOOOOOOOOOOOOOOOOOOOOO! – Ben Voigt May 07 '10 at 04:18
  • 2
    Except that it's "Certified 100% parentheses-free" :) – Pavel Minaev May 07 '10 at 19:14
  • @Pavel, except for tuples of course, and .net method calls – JaredPar May 09 '10 at 02:46
  • 27
    Two things of note here. First of all, tuples don't need `()` in F# - the `,` operator is what creates them, so `let x = 1,2` is a valid tuple already without any parens. Second, any pair parens in F# can be replaced by pairs of `begin`..`end` (this is inherited from ML) - so, for example, `"foo".IndexOf begin 'a', 1 end` is a valid .NET method call. So if you ever wanted to be parens-free, F# is one language that enables you to do just that :) – Pavel Minaev May 09 '10 at 22:34
  • Funny comment Pavel! Didn't know that. I think that in some cases with large grouping blocks, I might actually prefer `begin`..`end`. ALSO: VsVim RULES! – Dan Fitch May 13 '10 at 21:54
13

A lot of the unit tests for the F# Visual Studio components are written in F#. They run outside VS, mocking the various Visual Studio bits. The ability to cons up anonymous objects that implement interfaces is useful in place of a mocking framework/tool. I can just write

let owpe : string list ref = ref []
let vsOutputWindowPane = 
    { new IVsOutputWindowPane with
        member this.Activate () = err(__LINE__)
        member this.Clear () = owpe := []; 0
        member this.FlushToTaskList () = VSConstants.S_OK
        member this.GetName(pbstrPaneName) = err(__LINE__)
        member this.Hide () = err(__LINE__)
        member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
        member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
        member this.SetName(pszPaneName) = err(__LINE__)
    }            
DoSomethingThatNeedsA(vsOutputWindowPane)
assert( !owpe = expectedOutputStringList )

when I need an instance of e.g. an IVsOutputWindowPane to pass to some other component that will eventually be calling OutputString and Clear, and then inspect the string list ref object at the end of the test to see if the expected output was written.

Brian
  • 117,631
  • 17
  • 236
  • 300
  • Interesting, more evidence that the uptake of F# within Microsoft is certainly high. I didn't know you could create anonymous objects that implement interfaces in F# – Peter McG May 06 '10 at 23:28
9

We wrote a custom rules engine language using the Lex-Yacc implementation in F#

EDIT to include comment reply

There was no lex/yacc implementation in C#. (as far as we were aware, and the F# one was)

It would have been possible, but a downright pain to build the parsing ourselves.

This topic shows some other suggestions, such as external libraries, but our lead architect is an old hand at functional languages, so the choice to use F# was a no-brainer.

Community
  • 1
  • 1
johnc
  • 39,385
  • 37
  • 101
  • 139
  • +1 You would have previously written this in C# was it unsuitable or slower for a certain reason? – Peter McG May 06 '10 at 23:58
  • @Peter McGrattan At least at the time of writing (the software), there was no lex/yacc implementation in C#. It would have been possible, but a downright pain to build the parsing ourselves. http://stackoverflow.com/questions/540593/lex-yacc-for-c shows some other suggestions, but our lead architect is an old hand at functional languages, so the choice to use F# was a no-brainer – johnc May 07 '10 at 00:21
  • if you thought there was no lex/yacc for C# I'm affraid you simply didn't look hard enough for it (There is one older than F#) that said if you need lex/yacc F# is in my opinion a much better suited hammer for that nail than c# – Rune FS May 07 '10 at 07:59
  • I used F# with fslex/fxyacc myself, though not in a "production" project (not released yet, anyway) - MSIL syntax highlighting and code completion extension for VS. The major benefit of using F# there is that you get ADTs, which are very convenient to represent parse trees. Also, using zippers (http://en.wikipedia.org/wiki/Zipper_(data_structure)) makes it easy to do incremental lexing - and zippers, being functional, are easier to concisely manipulate in F#. – Pavel Minaev May 07 '10 at 19:16
7

I'm currently working on a compile for a programming language. The compiler is written entirely in F#. The compiler (aside from the lex and parser build with lex/yacc) is basically build as a lot of transformation of a complex tree like structure.

As noted by others discriminate unions and pattern matching makes working with this kind of data structure a lot easier than dumping the code in virtual methods "all over the place"

I hadn't done any F# work before I started working on the compiler (I had however buld compilers in another OCaml variant called MoscowML) and just as Jared states it's visible from the code what parts I did first but in general I found F# easy to learn getting in to the FP mind set again after coding mainly OO for a decade will take a bit longer though.

working with trees aside I find the ability to write declarative code the main benefit of FP (F# included) having code that describes the algorithm Im trying to implement in contrast to C# describing how I've implemented the algortihm is a huge advantage.

Rune FS
  • 21,497
  • 7
  • 62
  • 96
6

Not personal experience, but you can listen to an episode of DNR (I think it's this one) where they talk to Microsoft folk about F#. They wrote most of Xbox Live scoring system, which was far from trivial, using F#. The system scaled massively across hundreds of machines and they were very satisfied with it.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
5

I don't know if it's in production, but the AI for "The Path of Go" was written in F#:

http://research.microsoft.com/en-us/events/techvista2010/demolist.aspx#ThePathofGo

The Path of Go: A Microsoft Research Game for Xbox 360

This demo showcases an Xbox 360 game, based on the game of Go, produced in-house at Microsoft Research Cambridge. Go is one of the most famous board games in East Asia, it originated in China 4000 years ago. Behind the deceptive simplicity of the game hides great complexity. It only takes minutes to learn, but it takes a lifetime to master. Although computers have surpassed human skills at Chess, implementing a competitive AI for Go remains a research challenge. The game is powered by three technologies developed at Microsoft Research Cambridge: an AI capable of playing Go, the F# language, and TrueSkill™ to match online players. The AI is implemented in F# and meets the challenge of running efficiently in the .net compact framework on Xbox 360. This game places you in a number of visually stunning 3D scenes. It was fully developed in managed code using the XNA environment.

(Someone else mentioned "TrueSkill" already.)

Brian
  • 117,631
  • 17
  • 236
  • 300
  • Fascinating: F# running on the compact framework on XBox. Doesn't FSharp.Core.dll along with FSharp.Core.optdata FSharp.Core.sigdata reference non-CF assemblies? – Peter McG May 06 '10 at 23:41
  • 1
    The CTP ships with a separate FSharp.Core that's build for .NETCF. (There's also a separate FSharp.Core for Silverlight.) – Brian May 06 '10 at 23:47
  • What is this CTP you speak of? – Jwosty Dec 27 '12 at 04:42