Getting Functional with F#

Today, .NET developers using only Microsoft's solutions have the chance to use Visual Basic, C#, and C++ to develop their applications. All three of these languages are based on a programming paradigm (model) called imperative programming where you as a developer specify the exact steps to solve the problem at hand. This is done by using statements in the correct order, but also with the help of variables and instances of classes to store the state of the application.

Although this model of programming is very useful in many situations (outside the domain of programming, furniture assembly instructions and cooking recipes are also examples of imperative programming), it is not the best method for every task. This is the reason functional programming was developed.

Functional programming is closer to the mathematics you learned at school than languages such as C#. However, this is not to say that functional languages are useful only for calculations. In fact, you can do all the same things in functional languages such as F# as you can do with C#. Only the way you do it differs.

In functional languages, the main question is what kind of data you need, and what should be done with the data. Furthermore, in functional languages, the concept of a function is fundamental. As you will soon learn, this also means that maintaining state is not important anymore. Contemporary examples of functional programming languages include XSLT, LINQ, and of course, LISP. For .NET developers, F# is the new kid in town.

Introducing the F# Language

F# started as a research project of Microsoft Research, and since then has grown to become the most probable candidate of being the first functional language to be included with Visual Studio. Although the term functional might in your mind be somewhat a limiting factor, the good thing about F# is that it supports object-oriented constructs, and also has full access to the .NET Framework.

If you are familiar with languages such as C#, you might at first find that F# is at the same time both familiar and unfamiliar to you. For instance, if you wanted to print out an array of numbers multiplied by two in F#, you could write code like this:

let timesTwo x = x * 2
let numbers = [1; 4; 5; 7; 12]
let numbersTimesTwo = List.map timesTwo numbers
printfn "Numbers = %A" numbersTimesTwo

These four lines introduce you two important concepts in F#: defining functions and lists, and standard functions of the language such as List.map. Of course, if you wanted to write the canonical "Hello, World" example, the "printfn" function would be your best friend.

Another typical example of functional languages is the way functions are created and used. Consider the following example to calculate the factorial (factorial is the product of numbers from 2 to n, so that, for example, 5! equals 2*3*4*5 = 120):

let rec factorial n = if (n = 0) then 1 else (n * factorial(n-1))
let x = 5
let f = factorial(x)
printfn "%d! = %d" x f

In functional languages, recursion is used instead of regular loops, and F# is no exception. In both of the above code listings, the first code line defines a new function with the "let" keyword. In the second example (above), the "rec" word tells F# that the function "factorial" is used recursively. Here is another listing, which finds numbers in an array that are larger than five:

let numbers = [1; 4; 5; 7; 12]
let largeNumbers = List.filter (fun x -> x > 5) numbers
printfn "Large numbers = %A" largeNumbers

Here, the List.filter function takes a function parameter (defined with the "fun" keyword), and executes it for each element in the list. Compare this to a snippet of C# code with LINQ:

int[] numbers = { 1, 4, 5, 7, 12 };
var largeNumbers = numbers.Where(n => n > 5);
foreach (int num in largeNumbers)
   MessageBox.Show(num.ToString());

As you can see, functional programming code looks familiar, but at the same time also can get a little used to, especially if you compare it to the rather straightforward manner of many C# applications. Even though functional languages in general are their best in algorithm implementations and in sectors such as financing, statistics, and mathematical research, F# can be used in much broader ways.

Consider, for example, the following code to retrieve the latest USD to Euro exchange rate from the European Central Bank (ECB). To use the code, you need to add a reference to the System.Xml.dll assembly file in your solution:

let ecbXmlUri = "http://www.ecb.europa.eu/\
   stats/eurofxref/eurofxref-daily.xml"
let xpathNavi =
   System.Xml.XPath.XPathDocument(ecbXmlUri).CreateNavigator()
let resolver = System.Xml.XmlNamespaceManager(xpathNavi.NameTable)
let xmlNsEcb = "http://www.ecb.int/vocabulary/\
   2002-08-01/eurofxref"
let xmlNsGm = "http://www.gesmes.org/xml/2002-08-01"
resolver.AddNamespace("ecb", xmlNsEcb)
resolver.AddNamespace("gm", xmlNsGm)
let nodePath = "/gm:Envelope/ecb:Cube/ecb:Cube\
   /ecb:Cube[@currency = 'USD']"
let node = xpathNavi.SelectSingleNode(nodePath,resolver)
let rate = node.GetAttribute("rate", "")
printfn "USD to Euro exchange rate is: %s." rate

As you can see from this listing, you can fully utilize the .NET Framework in your F# applications. In fact, you could view F# as a hybrid language, supporting both functional and imperative constructs. The above code would look much the same if it had been written with C#, for instance.

That said, classes, objects, and interfaces can all be used in F#. The language lets you build your own classes and interfaces as well. By the way, note some interesting syntax in the above listing. For instance, long strings can be split into multiple lines with the backslash character.

A (Parallel) Database Example

The previous listing gave you a hint that the whole .NET Framework versions 2.0 and later are accessible from F#. Now, assume that you would like to build a simple database application to read data from an SQL Server database. As you are surely aware, using ADO.NET is usually the best solution to do this, and so you would use the connection, command, and reader (for instance) classes from the System.Data.SqlClient namespace.

Here is an example of how to read data from the old, yet familiar Northwind database:

let connStr = "Data Source=.;Initial Catalog=Northwind;\
               Integrated Security=True;"
let conn = new System.Data.SqlClient.SqlConnection(connStr)
let sql = "SELECT [employeeid], [firstname], [lastname]\
           FROM [employees]"
let cmd = new System.Data.SqlClient.SqlCommand(sql, conn)
conn.Open()
let reader = cmd.ExecuteReader()
reader.Read()
printfn "Name = %s %s" (reader.GetString(1)) (reader.GetString(2))
reader.Close()
cmd.Dispose()
conn.Dispose()

Again, F# provides a quite straightforward way of accessing data with ADO.NET. As you can see, it is easy to convert C# code to F#, because the classes and methods calls you need to make stay the same.

Of course, things get more interesting for F# if you add some calculations into the mix. For instance, you might need to calculate the price of items with sales tax included. To retrieve the data from the database, you could use, for example, a LINQ query to get two arrays of values: one for the prices and another for the tax percentages for the given prices:

let prices = [100.0; 200.0; 50.0]
let taxPercents = [5.0; 4.0; 7.0]

With these two arrays, it would be simple to define a function called "calculateTax" that would calculate the correct price, and then run a List.map2 ("map2" is the method version that takes two parameters instead of just one) on these two lists:

let calculateTax price tax = price * (1.0 + (tax/100.0))
let results = List.map2 calculateTax prices taxPercents
printfn "results = %A" results

This would return a new array, "results," with values [105.0; 208.0; 53.5]. Of course, all this works nicely, but wouldn't it be great if you could somehow make this calculation use multiple threads to take better use of modern multi-core processors? With F#, this is almost as easy as 123!

F# supports built-in parallelism, and the "async" keyword. If you wanted to calculate the taxes in parallel, you would embed the List.map2 method call into an asynchronous context:

let results =
   Async.Run (Async.Parallel [
   async { return List.map2 calculateTax prices taxPercents } ])

That is all you need! Of course, with only three elements in the array, it would actually take longer to calculate the taxes in parallel because of threading overhead, but if you would have three hundred thousand items instead, the differences would start to show.

Getting Functional with F#

Installing F# into Visual Studio

If you attended Microsoft's PDC 2008 (Professional Developer Conference) in Los Angeles in late October and early November, or viewed the many F# sessions online, you might have noticed that Microsoft plans to make F# a fully supported Visual Studio language. This means that all users who use Visual Studio (presumably the next 2010 version), would get support for F#, just as they get support for C# and Visual Basic .NET today.

However, at this writing, F# is currently in the Community Technology Preview (CTP) stage, the latest version being 1.9.6.2 from September, 2008 (see Figure 1). The CTP requires Visual Studio 2008 to operate, but as with other .NET languages, you also have the option to use the command-line compiler, fsc.exe. The current download package for F# is about 14 megabytes in size.

[GettingFunct1.png]

Figure 1: The September CTP of F# requires Visual Studio 2008.

What's more, you also can use F# interactively, just like a PowerShell prompt, for example. The interactive version of F# is very useful for quick prototyping, and is available both as a standalone command-line version and integrated into the Visual Studio 2008 IDE. The command-line version is named fsi.exe (see Figure 2).

[GettingFunct2.png]

Figure 2: F# can also be accessed interactively from the command line. A command-line compiler is also available.

Inside the Visual Studio IDE, you can open the interactive F# interpreter by using the View/Other Windows/F# Interactive menu command, or by pressing Ctrl+Alt+F. Naturally, you must install the F# installation package first for this to work (see Figure 3). To quit the console in the command-line version, type "#quit;;". Yes, two semicolons are needed; this is the standard statement separator.

[GettingFunct3.png]

Figure 3: Integrating F# with Visual Studio brings new menu commands to the IDE.

Currently, the overall Visual Studio integration is useful, but not yet fully ready. For example, you cannot start a WPF or web application project with F#. Instead, you currently have to use code-only files without any visual designers. In addition, basic F# code files (ones with the .fs file extension) look very plain: they just have the "#light" directive, which enables the so-called lightweight mode. Below that line, you would write your own code.

F# allows you to separate your code into modules and separate .fs code files to enable code reuse (see Figure 4). However, with this CTP version, it appears that the file that actually gets executed first is dependent on the order of which the code files are added to the project.

[GettingFunct4.png]

Figure 4: Starting a new or adding a new F# module begins with the New Project dialog box.

That is, the order the .fs files are referenced in the .fsproj XML project file is used. You can use Visual Studio's Solution Explorer popup menu commands to move items up and down. Luckily, this only affects modules that do not reference each other.

Conclusion

F# is a functional language, but with a twist: It supports object-oriented programming and thus all the aspects of the latest .NET Framework. If you are familiar with languages such as C#, a functional way of programming might take some time getting used to, but the more you let yourself learn the language, the more useful it can become.

In this article, you learned the basic features of the F# language, and why and where it is useful. By looking at the code examples, you should get a good glimpse of what is possible, especially when business applications are concerned. Of course, there is a lot more to a language than a single article can teach you, but each journey starts with a small step.

In the future, F# is without doubt going to grow in importance. Most probably, the next version of Visual Studio, version 2010, will contain support for F# built-in. Although the whole .NET is at your disposal from F# applications, the best places to use F# might be rapid prototyping, algorithm implementation, mathematical functions, and everything where "programming in the small" is sought.

Until then, let us get functional!

Jani Järvinen

Links

The following links will help you get started with the F# language.

About the Author

Jani Järvinen is a software development trainer and consultant in Finland. He is a Microsoft C# MVP and is a frequent author, and has published three books about software development. He is the group leader of a Finnish software development expert group named ITpro.fi. His blog can be found at http://www.saunalahti.fi/janij/. You can send him mail by clicking on his name at the top of the article.



About the Author

Jani Jarvinen

Jani Jarvinen is a software development trainer and consultant in Finland. He is a Microsoft C# MVP, a frequent author and has published three books about software development. He is the group leader of a Finnish software development expert group at ITpro.fi and a board member of the Finnish Visual Studio Team System User Group. His blog can be found at http://www.saunalahti.fi/janij/. You can send him mail by clicking on his name at the top of the article.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • QA teams don't have time to test everything yet they can't afford to ship buggy code. Learn how Coverity can help organizations shrink their testing cycles and reduce regression risk by focusing their manual and automated testing based on the impact of change.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds