RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


An Introduction to F# for Functional Programming

Functional programming with F# is much more than writing good code. It is about enjoying writing code quickly and effectively.

his series of articles addresses functional programming, the main concepts and differences compared to other paradigms, and how F# helps you get up to speed and produce results. This article quickly lays the groundwork and then guides you on translating and/or interfacing with your existing code.

There is a great story about a man who came to the king's palace and claimed that he could answer any question. When no one could really challenge him the king pointed to a tree far away and asked how many leaves it had. The man took almost no time before he answered some exact and rather large number. How could anyone check that the man actually gave the right number? Well, the king and his advisors being smart fellows silently ordered a servant to run to the tree and take off 20 leaves, and upon his return asked the man once again to count the leaves. Just as before, he was quick to give another large number that was exactly 20 less than the first—after which no one doubted him anymore.

Apart from the implications in computational complexity—mainly that it is easier to design an algorithm to verify an alleged result than to come up with one that produces the right result—an important lesson is to think unconventionally and apply clever and well-founded ideas to produce success. Functional programming, when contrasted with other paradigms, is exactly like that: a handful of simple yet extremely powerful ideas put together that require a different way of thinking; one that may seem unconventional if you are a hardcore imperative programmer, but one that opens up new worlds and an unparalleled productivity when coupled with the right tools and technologies.

In February 2008, S. Somasegar, Microsoft SVP—Developer Division, announced that F#, Microsoft’s new functional programming language, will become a first-class citizen in the .NET ecosystem and a fully-supported language in Visual Studio. This synergy of simple-yet-powerful concepts, meeting the right platform and abundance of tools and technologies, opened the eyes of many developers. Microsoft’s announcement has helped F# gain increasing popularity and sparked the interest of professional developers.

What is F#?

F# lets you do imperative programming if you need low-level control, but after you master the functional way of thinking, you will find little use for this and will appreciate the more abstract code that you get in the functional style. In this article you will only see the functional and object-oriented features presented.
F# shares common roots with the so-called ML family of languages (SML, OCaml—taught in many universities and used for research, yet little known elsewhere) but has followed a different path since its inception in 2002 in a Cambridge Microsoft Research lab, under the direction of Don Syme—one of the main designers of .NET Generics and a key player in much of Microsoft’s programming language research.

F# is a functional, object-oriented language that compiles to run on the Common Language Runtime (CLR)—it is built around a small and powerful functional core language, and features a complete set of object-oriented extensions that enable it to work seamlessly with other .NET languages. F# combines the expressiveness of dynamic languages with the power of statically typed ones (in F#, every value has a well-defined type, be that polymorphic or not), which coupled with a powerful type system (the compiler tells you what you did wrong before you run your program) and type inference (no need to annotate your code with types) makes your F# code shorter, more elegant, easier to understand, maintain, and extend than other .NET languages.

Getting Started
F# operates in two modes: one that understands the standard, traditional syntax, and one that features a simplified, more concise syntax that uses fewer keywords and enforces certain formatting rules that reflect scoping via indentation. This latter mode is called the #light mode, and it is initiated by entering #light—usually on the first line of your program file. In the remainder of this article, you should turn on #light mode, as shown in Listing 1.

F# comes with an incredibly useful tool called F# Interactive, a top-loop that is available to you either as a standalone program (fsi.exe) or as a Visual Studio add-in (see Figure 1). To use the add-in, first you need to enable it, then you can activate it by highlighting parts of your F# code and pressing Alt+Enter to send the highlighted text to it. The code you enter or send to the add-in will be parsed, compiled, and evaluated on the fly—and you can examine return values and their types easily. You can use this interactive session to test pieces of your code, interact with it dynamically by entering arbitrary expressions, etc.

Figure 1. Running F# Interactive as a Visual Studio Add-in: Using the interactive top-loop makes your life much easier--no need for lengthy compilation-test-fix cycles; you can evaluate pieces of your code on the fly.
You can also use code completion (press the Tab key) to show available code alternatives at any time. If you are typing directly into the interactive session (on the command line starting with >) you can close a code block using double semicolons. This sends the given block into the interactive session, which responds with either an error message, or a value binding and its type.

Functional Basics—Types, Values, and Bindings
In a nutshell, functional programming helps you to better abstract your values and the way you operate on them. To accomplish this, you have—beyond the ordinary standard data types and classes—a handful of key data abstraction mechanisms:

  • Discriminated unions (these help you create closed data representations)
  • Tuples and records (these let you bundle data more easily)
  • Function types (that allow you to define and enforce signatures)
  • Polymorphic abstract data types (these let you express generic structured data)
  • Sequences (collections that you can work with on demand—for instance, you could create an infinite stream of random numbers and read as many as you like)
You can define these types in as little code as:

// A person has a name and an age.  Represented as a record.
type Person = { name: string; age: int; }

// A pair/tuple that represents a name and its validity.
type NameValid = string * bool

// A generic predicate type (a function that maps values to booleans).
type 'a predicate = 'a -> bool

// The following are equivalent:
type IntList = int list
type IntList' = List

// All natural even numbers represented as a (nearly) infinite sequence.
let evenNumbers = seq { 0 .. 2 .. Int32.max_int }
The last code line is a value definition—binding a value to a name. Here it appears as a top-level binding (meaning on the module level), however let bindings can occur anywhere in your programs, making it easy to introduce local functions and definitions nested at an arbitrary level.

Functional programming treats functions as first-class values, just like any data value, so you can embed functions in any data structure and pass them to or return them from other functions. Such functions are called higher-order functions. This capability lets functional programming languages incorporate object-oriented features easily, because a class type is simply a record with some function fields .

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date