views:

2887

answers:

11

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 it's 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 it's 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#.

EDIT: Edited based on feedback from close votes with the intent of reducing perceived ambiguity.

+6  A: 

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
+26  A: 

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
Very interesting, more evidence that the uptake of F# within Microsoft is certainly high, what a great internship that must have been!
Peter McGrattan
+7  A: 

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
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 McGrattan
+4  A: 

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
Fascinating: F# running on the compact framework on XBox. Doesn't FSharp.Core.dll along with FSharp.Core.optdataFSharp.Core.sigdata reference non-CF assemblies?
Peter McGrattan
The CTP ships with a separate FSharp.Core that's build for .NETCF. (There's also a separate FSharp.Core for Silverlight.)
Brian
+4  A: 

The WebSharper folks have built a whole product that's centered on F# for web programming. Here's an article that talks about it:

http://www.sdtimes.com/content/article.aspx?ArticleID=34075

Brian
+5  A: 

Here's a case study about a bank that uses F# along with C++/COM for stuff:

http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000006794

Brian
F# is used in most major banks: Citibank, Ronin Capital, UBS, ING...
Jon Harrop
+8  A: 

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.

johnc
+1 You would have previously written this in C# was it unsuitable or slower for a certain reason?
Peter McGrattan
@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
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
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
+12  A: 

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
Editor ... functional language ... vi emulation ... you've re-invented emacs. NOOOOOOOOOOOOOOOOOOOOOOO!
Ben Voigt
Except that it's "Certified 100% parentheses-free" :)
Pavel Minaev
@Pavel, except for tuples of course, and .net method calls
JaredPar
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
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
+5  A: 

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
+69  A: 

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
+1: very clear answer
ANeves
+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
Great answer, relevant, contemporary and outlines F# suitability for dealing with complexity, I learnt a lot from reading it, thanks
Peter McGrattan
Great answer Simon, and as Don mentioned last night, quoted in his recent slides. Time to add an "add to cart" link?
Chris Ballard
+1..for shits and giggles
Luke101
+12  A: 

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.

Jon Harrop