In What Areas Might the Use of F# Be More Appropriate Than C#

In what areas might the use of F# be more appropriate than C#?

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.

What are the benefits of using C# vs F# or F# vs C#?

General benefits of functional programming over imperative languages:

You can formulate many problems much easier, closer to their definition and more concise in a functional programming language like F# and your code is less error-prone (immutability, more powerful type system, intuitive recurive algorithms). You can code what you mean instead of what the computer wants you to say ;-) You will find many discussions like this when you google it or even search for it at SO.

Special F#-advantages:

  • Asynchronous programming is extremely easy and intuitive with async {}-expressions - Even with ParallelFX, the corresponding C#-code is much bigger

  • Very easy integration of compiler compilers and domain-specific languages

  • Extending the language as you need it: LOP

  • Units of measure

  • More flexible syntax

  • Often shorter and more elegant solutions

Take a look at this document

The advantages of C# are that it's often more accurate to "imperative"-applications (User-interface, imperative algorithms) than a functional programming language, that the .NET-Framework it uses is designed imperatively and that it's more widespread.

Furthermore you can have F# and C# together in one solution, so you can combine the benefits of both languages and use them where they're needed.

Is F# really better than C# for math?

I think most of the important points were already mentioned by someone else:

  1. F# lets you solve problems in a way mathematicians think about them
  2. Thanks to higher-order functions, you can use simpler concepts to solve difficult problems
  3. Everything is immutable by default, which makes the program easier to understand (and also easier to parallelize)

It is definitely true that you can use some of the F# concepts in C# 3.0, but there are limitations. You cannot use any recursive computations (because C# doesn't have tail-recursion) and this is how you write primitive computations in functional/mathematical way. Also, writing complex higher order functions (that take other functions as arguments) in C# is difficult, because you have to write types explicitly (while in F#, types are inferred, but also automatically generalized, so you don't have to explicitly make a function generic).

Also, I think the following point from Marc Gravell isn't a valid objection:

From a maintenance angle, I'm of the view that suitably named properties etc are easier to use (over full life-cycle) than tuples and head/tail lists, but that might just be me.

This is of course true. However, the great thing about F# is that you can start writing the program using tuples & head/tail lists and later in the development process turn it into a program that uses .NET IEnumerables and types with properties (and that's how I believe typical F# programmer works*). Tuples etc. and F# interactive development tools give you a great way to quickly prototype solutions (and when doing something mathematical, this is essential because most of the development is just experimenting when you're looking for the best solution). Once you have the prototype, you can use simple source code transformations to wrap the code inisde an F# type (which can also be used from C# as an ordinary class). F# also gives you a lot of ways to optimize the code later in terms of performance.

This gives you the benefits of easy to use langauges (e.g. Python), which many people use for prototyping phase. However, you don't have to rewrite the whole program later once you're done with prototyping using an efficient language (e.g. C++ or perhaps C#), because F# is both "easy to use" and "efficient" and you can fluently switch between these two styles.

(*) I also use this style in my functional programming book.

Is F# better than C# in scenarios where you need complete parallelism in parts of an application?

I'd look at the Parallel Extensions that's being developed by Microsoft.

Which to use, C# or F#? In this real world case

This sounds like an application that can be written using both of the styles. Using F# seems appropriate and this is probably a good application for learning the F# language and functional programming.

Regarding the architecture, you wrote:

I don't know functional programming (yet), but from an OO perspective, some of the design seems straight forward: Make a Fish class, and derive these classes from it: Herring, Predator, Prey. Each should have properties such as position, direction and speed.

Functional programming isn't all that different. It emphasisez working with concrete types (and you don't use inheritance that often), so you would probably define distinct types such as Herring and Predator with similar properties. Then you would create lists of herrings and list of predators and perform step-by-step simulation of the two types separately.

Coincidentally, I wrote a similar simulation with "animals" and "predators" as a sample for my functional programming book (in both C# and F#). The source is freely available (look for Chapter 14), so you may find that as a useful inspiration (the sample also demonstrates parallelism). Using Excel from F# is also perfectly possible (in exactly the same way as in C#) and example is also available in my book (see source code for Chapter 13).

In general, solving the problem in F# using functional programming will require slightly different point of view, and you'll probably need to spend more time experimenting, but it seems like the problem could nicely benefit from some F# features (and it is a good chance to learn something new).



Related Topics



Leave a reply



Submit