F# (F-Sharp) is a .NET programming language that is automatically shipped with the latest version of Visual Studio. Ample reason to write a "Technology Letter" in order to show what F# is, what strengths the language possesses and when it makes good sense to employ it.
This Technology Letter is aimed first and foremost at C# and Visual Basic developers. It aims to show them how F# differs from the familiar languages.
What is F#
F# is a functional programming language from Microsoft that is totally integrated in the .NET-Framework. The language was originally developed by Microsoft Research as a research project and is now supported from the development department at Microsoft (Microsoft Developer Division). With Visual Studio 2010, F# is now officially available as a .NET language for the first time. For Visual Studio 2008, an add-on can be installed later.
F# is not a pure functional programming language; it also supports object-oriented and imperative programming. It can be used for example to write complete Windows Forms applications or access code written in C# or Visual Basic.
A probably even more interesting fact is that code written in F# can also be used without problem from C# or Visual Basic projects. One of the great advantages of the language is the fact that programme sequences lend themselves very easily to parallelization. This means that compute-intensive code can be stored in an F# library, which can easily be called up with the familiar language.
A brief explanation of functional programming
Most developers are familiar with imperative programming practiced with languages such as C++, C# and Java from their daily work. If you are used to imperative programming, functional programming can be most easily understood by showing what it is not.
Let us consider the following code snippets:
Where is the difference? In the left code snippet, a variable is created and assigned the value 1. In the second line, the value of the variable is increased by 5.
In the right code snippet, the same variable is created and also assigned the value 1. The difference to the left hand side is that the value resulting from the increase by 5 is stored in the newly created variable "y". If the value "x" is subsequently called up again, it will still return 1.
This seemingly small detail illustrates the fundamental difference between imperative and functional programming. With imperative programming (left) modifiable variables are employed. It provides for read and write access at various points in the code. Functional programming on the other hand, uses only fixed variables that are referred to as values by functional programmers. Values may be regarded as a type of constant.
Another characteristic of functional programmes is that they consist solely of functions that always return the same result if the parameters remain unchanged. Functions can in turn be passed on to other functions as a parameter.
Advantages of functional programming
What then are the advantages of functional programming?
Since functional languages tend to reflect an academic way of thinking and the majority of these languages also originated in the academic environment, they are especially suited to mathematical and scientific calculations.
Functional languages have much more to offer however!
The following section illustrates the three major advantages of functional programming.
The biggest and probably most important advantage of functional programming is the simple facility of parallelisation.
Nowadays, virtually no computers, let alone servers come without a multi-core CPU. Yet what is the point of all these cores if they are not utilised by the programmes?
Modern programmes should be written in such a way as to utilise these CPUs. Since functions work with fixed values and not with modifiable variables, it is much easier to distribute these among different threads or processes of the different cores. The work involved in synchronising variables is eliminated. Since the functions do not change their environment, the order of execution is irrelevant.
The correctness of the code becomes (more) verifiable
If a reference is made in the course of a calculation to state variables that are accessible from other parts of the programme, it is impossible to say what value will be stored. When testing, every possible value must be taken into account. If a number of state variables are referred to, the effort involved increases accordingly.
Moreover there is a possibility that"someone" amends code at a different point and overwrites the value of a state variable. His tests all run positively, yet our method now no longer yields the same return value as before. What might be desirable in the majority of cases, can lead to hard-to-locate errors in other cases.
Since state variables are not permitted in functional programming, there can be no so-called side effects. This in turn means that a function always has the same return value if the parameters remain unchanged. As a result, the correctness of the code is more provable and thus automatically verifiable.
Functional programming reduces the risk of including undesirable side effects.
Short and concise
Last but not least, the code of functional programming languages is often shorter and more concise. More can be achieved with fewer lines of code.
The following programming examples first show the syntax, then the advantages of the F# language and the reason why this is the case.
The "let" expression
The simplest type of function is a constant.
"let" allows an identifier to be assigned a value. In the first line, the value "pi" is assigned the number 3.1415927. F# works with type inference. This means that the values of the types do not have to be explicitly stated but are determined by the compiler. In this way, "pi" is automatically converted into a floating-point number, whereas "myInt" represents an integer.
In the following code, a function is defined as the sum of two parameters:
After the let comes the function name, followed by the parameters (param1 and param2). After the equals sign comes the function code (here the addition of the two parameters param1 and param2). The function can now be called up by the name "funcName".
Some programmers are probably yearning for the brackets here. In F#, function names, parameter definitions and code are separated solely with spaces and operands.
In the next code snippet, a function is created which as shown above, adds two parameters. In the second line, the function is called up and the result assigned the value "res" which is then displayed on the console in the final line.
It was stated above that brackets are not used when programming in F#. That's not entirely true. Brackets are essential for castings and to call up nested functions.
The two parameters are defined as double, which means that the result is also returned as double.
As a function is handed over as a parameter, a bracket is obligatory. In this way the values 3 and 5 can be determined to belong to the function "mul". The value of the function is then incremented by 4.
The following code shows how simple it is to call up asynchronous functions with F#.
First a list of names and associated URLs is produced. The function "fetchAsync" creates a link to the corresponding URL and selects all the characters on this page. In the next step, the number of occurrences together with the thread-ID of the function is provided.
The runAll method starts the "fetchAsync" method for each URL in the list asynchronously. Because the threadpool (.NET) is being used here, it is neither necessary nor possible to define the thread to be used to execute the function. Depending on the constellation, all calls are invoked with the same thread, the next time all with different threads.
In this case, two threads were used for the three calls:
Short and concise
In direct comparison to imperative programming, functional programming is often shorter and more concise, resulting in a significant improvement in legibility. The following code calculates the square for each number in an array and then the sum of all the squares.
The C-Sharp code might look roughly as follows:
Now, by way of comparison, the F# code that does the same:
Calculating with units
One special feature of this language is calculating with units. Not only does the language offer type security; it is also possible to calculate with units using the attribute "Measure".
The compiler ensures that metres are not confused with kilos.
The function average can only pass on float values with the units [km] and [h]. The return value is already given by IntelliSense as [km/h].
Integration of F# as a library in a C# project
Code written in F# may be used in the customary manner in other projects. All that is required is to add the DLL as a reference in the project.
A module with the following functions is implemented in the file SomeFunctions:
These may be called up like a method from a C# class:
The strength of F# undoubtedly lies in the depiction of mathematical problems and complex algorithms. Although object-oriented programming is possible with F#, calculations should be developed in F# libraries and utilised from projects written in familiar languages such as C# or Visual Basic.
F# is not limited to solving mathematical problems, however. A major benefit lies in the parallelisation where parts of the programme can or even must run in parallel. The code is not only less error-prone, but also easier to read and write than object-oriented languages.
F# not only has a significantly different syntax to C# for instance, it also demands a different way of thinking on the part of the developer. In this respect, a certain training period that should not be underestimated is unavoidable. On the other hand, it offers enormous benefits, especially in terms of parallelisation of applications.
You can find further information on the subject here:
If Visual Studio 2010 or the add-on for Visual Studio 2008 is installed, an F# tutorial can be opened as a project. A number of examples are available there.
The official Microsoft Internet sites are: