F# in 20 Minutes – Part I

Edit: If you are interested in learning F#, let me take the opportunity to provide a shameless plug for my book Programming F#.

Edit: Updated for the September CTP.

Edit: While I certainly encourage you to read my blog, there is a great video we did for PDC titled An Introduction to Microsoft F# at https://channel9.msdn.com/pdc2008/TL11/

With the September CTP hot off the presses, I figured it was time to write a concise, 20-minute introduction to F#. The goal isn't to teach F#, but rather give a quick overview of the language and some of the things you can do with it. I’ll divide the 20 minutes into three parts:

  • Part I - A slow introduction to F#, explaining your first program

  • Part II – A brisk overview of the foundational types and concepts in F#

  • Part III – A quick sampling into advanced topics

So if you're interested in seeing what the fuss is all about, the read on.

What is F# and why should I learn it?

F# is a functional programming language built on .NET. Just like C# and VB.NET, F# can take advantage of core libraries such as Windows Presentation Foundation, Windows Communication Foundation, Visual Studio Tools for Office, etc. With F# you can even write XBox games using XNA.

But just because you can write code in a new language doesn't mean you should. So why use F#? Because being a functional language, F# makes writing some classes of programs much easier than its imperative cousins like C#. Parallel Programming and Language-Oriented Programming are two such domains that can be expressed easily in F#.

If you’ve ever written a .NET application and found yourself fighting against the language to get your idea expressed, then perhaps F# is what you’ve been looking for.

Getting Started

To get started with F# download and install the latest release (v1.9.6.0) at:

Or just click ‘Download’ on the F# Development center at http://msdn.com/fsharp

This will install the F# Project System on top of Visual Studio 2008. First, create a new F# Project.


Next, add a new F# Source File. By default it will add a lot of ‘tutorial’ code, delete all that and insert the following into the empty code editor:


let square x = x * x

let numbers = [1 .. 10]

let squares = List.map square numbers

printfn "N^2 = %A"squares

open System

Press F5 to run your program, and you'll see the following:


Nothing terribly exciting yet. Let’s will break the code down the code line by line and then see if what’s really going on, but before we do that, let me introduce VFSI.

F# Interactive for Visual Studio

The F# Interactive Console (FSI) is what’s know as a ' REPL loop’ for Read-Evaluate-Print-Loop. This means: taking a code snippet, compiling and executing it, then printing the results. With it you can rapidly prototype and test your programs. To launch FSI simply highlight some code and press ALT+ENTER; the FSI window will immediately pop up.

What you just did was send the code snippet directly to the F# Interactive session, and the results were displayed to the output. The result was the definition of a function 'square' which takes a type 'int' and returns a type 'int'.

Next try typing "List.map square [1 .. 2 .. 10];;" into the FSI window. The ';;' indicates to FSI to stop reading in program text and evaluate the result.

> List.map square [1 .. 2 .. 10];;
val it : int list = [1; 9; 25; 49; 81]

Now we have the ability to easily explore the F# language via FSI, let's go into what that code actually means. I recommend however that you type code inside the Visual Studio code editor and use 'Highlight + ALT + Enter' to send the code to FSI. Otherwise, you will have to retype your code very time you have a typeo. (Which, at least for me, is very often.)

Language Basics

#light (OCaml compat)

F# has its roots in a programming language called OCaml and has the ability to cross compile OCaml code, meaning that it can compile simple OCaml programs unmodified. This ability however, means that F# requires some unsavory syntax by default. #light (pronounced hash-light) is a compiler directive that simplifies the syntax of the language.

I highly recommend that you keep #light on since most F# code snippets you find will either declare it, or assume that it has been declared.

let square x = x * x (Type Inference)

This defines a function called 'square' which squares a number x. Consider for a moment the equivalent C# code:

public static int square(int x)
return x * x;


Whereas C# requires you to specify type information as well as what the function actually returns, the F# compiler simply figures it out for you. This is referred to as type inference.

From the function signature F# knows that square takes a single parameter named 'x' and that the function would return 'x * x'. (That last thing evaluated in a function body is the ‘return value’, so no need for a ‘return’ keyword.) Since many primitive types support (*) such as byte, uint64, double, etc. F# defaults to int, a signed 32-bit integer.

Now consider the following code which provides a 'type annotation' for one of the parameters, that is telling the compiler the type to expect. Since x is stated to be of type 'string', and (+) is only defined for taking two strings, then the parameter y must also be a string. And the result of x + y is the concatenation of both strings.

> let concat (x : string) y = x + y;;
val concat : string -> string -> string

> concat "Hello, " "World!";;
val it : string = "Hello, World!"


We'll cover more advanced topics in type inference later. But for now just enjoy the fact that the F# compiler has the smarts to figure out what you mean, and doesn't require any hand holding.

let numbers = [1 .. 10] (F# Lists)

The next line simply declares a list of numbers one through ten. If you had typed [|1 .. 10|] that would have created a .NET array of integers. But an F# list is an immutable linked list, which is the backbone of functional programming. Try typing these things into the FSI window (remember to add a ‘;;’ at the end of each line):

// Define a list
let vowels = ['e'; 'i'; 'o'; 'u']

// Attach item to front (cons)
let cons = 'a' :: vowels

// Concat two lists
let sometimes = vowels @ ['y']

I’ll cover lists more in-depth in Part II.

let squares = List.map square numbers (List.map and first-order functions)

Now we have a list of integers ('numbers') and a function ('square'), we want to create a new list where each item is the result of calling our function. In other words, mapping our function to each item in the list.

Fortunately, List.map does just that. Consider another example:

> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]


The code (fun i -> i % 2 = 0) defines an anonymous function, called a lambda expression, that has a parameter x and the function returns the result of "x % 2 = 0", which is whether or not x is even.

Now notice what we just did - we passed a function as a parameter to another function. You simply can't do that in C#. (At least not easily.) But in F# it allowed us to be very expressive and succinct in our code. Passing around functions as values is known as 'first order functions' and is a hallmark of functional programming.

printfn "N^2 = %A" squares

printf is a simple and type-safe way to print text to the console window. To get a better feel for how printf works consider this example which prints an integer, floating-point number, and a string:

> printfn "%d * %f = %s" 5 0.75 ((5.0 * 0.75).ToString());;
5 * 0.750000 = 3.75
val it : unit = ()


The %d, %f, and %s are holes for integers, floats, strings. %A may also be used to print anything else.

Console.ReadKey(true) (.NET Interop)

The last line in our program was simply a call to System.Console.ReadKey, in order to pause the program before it closed. Since F# is built on top of .Net you can call any .NET library from F# - from Regular Expressions to WinForms. The line ‘open System’ simply opened the namespace and brought its types into scope, similar to the using keyword of C#.

Now that we have the absolute basics out of the way, we can move onto the more interesting foundational types and concepts of F# so stay tuned for Part II!

Comments (66)
  1. R says:

    Interesting posting!

    It seems to require the full version of VS, though. How would one go about using it with free Express editions?

  2. Brian and Chris have been writing some great blog posts of late on learning F#. I can highly recommend

  3. secretGeek says:

    Great introduction Chris!

    @R, re: "require the full version of VS..?"

    If you don’t have Visual Studio, then you can run F Sharp Interactive as a console application (instead of a visual studio window).

    The compiler and tools don’t require Visual Studio — they just offer Visual Studio integration as a "value add" feature.

    Visual Studio express prohibits add-ons, so that kind of kills its ability to benefit from FSI. (Don Syme wrote answered a question about that here: http://cs.hubfs.net/forums/thread/3434.aspx )

  4. Peter Gum says:

    Terrific! Just the right level of explanation that I badly need. Keep it up.

  5. Jan Midtgaard says:

    "Passing around functions as values is known as ‘first order functions’ and is a hallmark of functional programming."

    No, it’s called ‘first-class functions’ (because functions are first-class citizens, like, e.g., numbers) or ‘higher-order functions’ — not ‘first-order functions’. Languages with ‘first-order functions’ don’t pass them around.

  6. James Hurst says:

    I appreciate your article, and just want to point out a couple of items that could perhaps be improved. For beginner’s tutorials, little syntax errors can be confusing.

    1. Under "printfn "N^2 = %A" squares", do you mean to say "printf is a simpler.." or "printfn is a simpler"? These look like two distinct things to me (I’m a noob obviously).

    2. Under "let numbers = [1..10]", how’re we supposed to type these lines into the FSI window? Exactly as is? Nothing happens. Do you intend for us to use the ";;" syntax to cause the line to execute? That yields an error. You might want to be a bit more explicit yet at this point to avoid frustrating your readers.

    3. Under the picture of the FSI window, where you instruct your user to type "[1 .. 2 .. 10]" – an explanation of what the heck that IS, would be helpful here!

    4. I’m guessing that "FSI" means "F Sharp Interactive" – but perhaps you could say that explicitly?

    5. Where you give instructions on how to use the Add-in Manager to add the FSI window, you could stand to be a bit more explicit (IMO). You leave us with that Add-in Manager still open! What about those other two checkboxes – "Startup" and "Command Line"? Do you intend for us to click "OK" here before continuing on to your next step?

    6. You skip a few beats in instructing your readers in creating their first F# project. "Add a new F# Source File"? Don’t you need to let them know that they first need to create a project? And what about all that code and comments that come pre-loaded within that new F# source file I created? What’s up with that? Do we need to delete it all first?

  7. Jonathan Pryor says:

    Minor quibble:

    > Now notice what we just did – we passed a function as a parameter to another function. You simply can’t do that in C#. (At least not easily.)

    For C# we can make the distinction between definition and use.  Definition is more verbose, due to the need for types, but it’s not impossible either — you simply use a Delegate type:

    class List {

     public static TOutput[] map<TInput, TOutput> (Func<Tnput, TOutput> f, TInput[] input) {…}


    Usage would actually be similarly verbose to F#:

    var squares = List.map (square, numbers);

    List.map (x => x % 2 == 0, new int[]{1, /* … */ 10});

    The overhead here is the array creation, not the lambda expression.

    (And in this case, using System.Array.Convert() would make more sense than defining a new List.map method.)

  8. ChrSmith says:

    Thanks for the feedback, I’ll update this post to (hopefully) clarify things more.

    And if I need to remember to write out:

    public static TOutput[] map<TInput, TOutput> (Func<Tnput, TOutput> f, TInput[] input) {…}

    every time I pass declare method which takes a function as a parameter, I consider that hard to do. Even if the call-site code is clean 😉



  9. IanS says:

    @R, re: "require the full version of VS..?"

    You can use F# with the free Visual Studio 2008 Shell. See the following for more info:



  10. Great article; looking forward to the rest of the series.  I’ve been meaning to look at F#, and this looks like a great quick intro.

    On the comparison to C#, I’d like to echo the previous comment that it’s actually quite easy to pass a function to a function.  And, in fact, the System.Linq namespace already defines an equivalent of "map."  Your full example looks something like this in C#:

    using System;

    using System.Linq;

    class Program


       static void Main()


           Func<int, int> square = x => x * x;

           int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

           var squares = numbers.Select(square);

           Console.WriteLine("N^2 = {0}", squares.Aggregate("", (s, i) => s + " " + i));




    Note that the hard part is declaring the sequence (which of course would be easier if there was an "Enumerable.Sequence" method or somesuch), and formatting the output.

    Another approach, more in the spirit of the latest wave of C# features, would be:

       static IEnumerable<int> Sequence(int start, int end)


           for (int i = start; i < end; i++)

               yield return i;


       static void Main()


           var squares = from x in Sequence(1, 10) select x * x;

           Console.WriteLine("N^2 = {0}", squares.Aggregate("", (s, i) => s + " " + i));



    And it’s not true that declaring a function that takes a function arg is necessarily as verbose as declaring "map" is; that example is complicated by the fact that "map" has to be generic.  I wonder what the declaration of "map" looks like in F#?  Don’t you have to do something special to keep the compiler from assuming all the types are "int," like it did for your "square" function?

    Love the interactive evaluation thing.  That might make me pick up F# all by itself.

    Thanks again for the article!

  11. Now that we have covered the basics, in minutes 8 – 14 we will cover the foundational concepts and types

  12. Anders Cui says:

    从Allen Lee的《从C# 3.0到F#》一文开始,感觉园子里F#正在升温。Chris Smith写了一个F#的小系列,这里翻译出来与大家分享。在本文从零开始编写我们的第一个F#程序。

  13. Ron Mitchell says:

    Tried to install the latest F# CTP where the platform is "Vista Ultimate" and VS 2008…hmmm – install dies saying that it not an appropriate MSI file???



  14. ChrSmith says:

    Hey Ron, could you be more specific. What was the exact error message you recieved? Please send it to fsbugs@microsoft.com.


  15. Matthew Doig says:

    Good little intro to f#.  I used this for my initial lesson when learning f#.  If you’re a VB programmer you may want to take a look at the series of blogs i’ve just started.


  16. Alex says:

    Unfortunately – as it seems, F# developers decided to use the way of the such aincient programming languages as Fortran – minimal type control, maximal possibility to make errors. If I am right, it’s a mistake. The banner of this way could be expressed (using gross exaggeration in order not to say too much words) as follows – we will write the code as soon as possible (<all the rest will not be said to customers> but then we will look for the mistakes all the life remaining). Making mistakes is usual way for the middle-level programmer, F# will help him to do that?

  17. Matt Galligan says:

    With F# being presumably distilled into the same CLI, does using F# confer any speed advantages to the same logically-identical function in C#/etc?

    Basically, I’m wondering for intensive math calculations (such as stuff for http://projectueler.net), will F# confer a speed of execution advantage?

  18. Chris Smith says:

    Since C# and F# both compile down to IL and get executed with the same JIT engine, there is no distinct speed ‘advantage’ for using one language over the other. F# should have the same performance profile as C#.

    Any significant difference in benchmarks is usually due to different algorithms being used.

  19. maveric says:

    Yes this is quite good . And what more advantanges with this lang.  

  20. Rupert says:

    Hi I’d like to know (as mentioned by somebody above) what List.map square [1 .. 2 .. 10];;

    I can see from the result that it’s outputting the squares of 1, 3, 5, 7 and 9 but I’m at a bit of a loss as to why!

    Thanks, great article by the way.

  21. Excellent.. I am very much impressed the way you explained about the functional programming language F#. I also keep the specification document for F# when i am reading this post. Twice i turned to spec document for :: and @ operators meaning.

    Enjoyed writing F# code … i am really become the fan of F# language after reading your blog. Thank you so much. Eagerly Waiting for second part. 🙂

  22. int19h says:

    There may be some performance advantage in the fact that F# does tail call optimization where it can (C#, in contrast, never does it).

  23. Great introduction to F# for beginners, thanks.

  24. anon says:


    List.map square [1 .. 2 .. 10];;

    2 must be increment by: 1+2=3+2=5+2=7+2=9

  25. ASPInsiders says:

    First, let me remind you that in my new ongoing quest to read source code to be a better developer ,

  26. First, let me remind you that in my new ongoing quest to read source code to be a better developer ,

  27. echostorm says:

    It can be even easier in C# than Eric’s.

    MessageBox.Show(Enumerable.Range(1, 10).Select(a => a * a).Aggregate("", (b, c) => b + " " + c));

  28. cbmeeks says:

    Very nice tutorial.  I hope to learn some F# soon and this really helped.

  29. Jason says:

    Just learn Python and use IronPython and be done with it. Too many languages create vertical markets. VB dropped "let" 20  years ago, why bring it back?

    I was hoping to see something tuly nice, and readable:

    numbers = range(1,10)

    print "N^2="+str([x*x for x in numbers])

    Oh wait, that is python. If you feel the need to use a map construct:

    def square(n):

       return n*n

    print "N^2="+str(map(square, numbers))

    What is more readable?

  30. Ian Marteens says:

    F# is more readable and powerful, of course.

    There’s no obligation about learning functional programming, but it’s an important part from Computer Sciences, and, if you want to compare two different languages as Python and F#, you should know the basic concepts behind FPLs for making a sensible evaluation.

  31. Srinivasan S Saripalli says:

    I have F#ver1.9.6.2 installed on my machine.Since I dont have VS2008 installed,I run F#I Console.I have executed the below two lines of code

    let vowels = [‘e’,’i’,’o’,’u’];;

    let attacha = ‘a’ :: vowels;;

    however i get the below errors

    let attacha = ‘a’ :: vowels;;


    stdin(15,22): error FS0001: Type mismatch. Expecting a char list but given a ( char * char * char * char) list

    the type char does not match the type ‘char * char * char * char’.

    Can anybody please explain why I get the above error.

    I certainly feel that to learn F# C# is not a criteria,because I dont know C# but I am primarily a VC++ guy.


    Srinivasan S Saripalli


  32. ChrSmith says:

    The problem is the way you declared the list:


    is a list of characters (semicolon delimited)


    is a single-element list, which is a tuple of 4 characters. (Duples are comma delimited.)

    Make sense?

  33. anon says:

    The reason it didn’t work Srinivasan is because you separated the list elements with commas instead of semicolons. Comma separation creates a tuple, or compound type, so what you actually made there was a list with one element, a tuple of four chars, instead of a list with four char elements.

    This article should explain it better than I can:


  34. anon says:

    Whoops, sorry Chris, for some reason your answer wasn’t showing up on my browser until after I posted mine.

  35. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  36. Hello,

    The programs below are well received. However an expensive source code (MATLAB) is used. Several potential users would like to use an open source code like F#. Is it suitabel to use F# to solve differential equations?

    Research reactor


    Chernobyl avalanche


  37. ChrSmith says:

    Re: "Is it suitabel to use F# to solve differential equations?"

    Certainly. F# seems to be very productive in highly algorithmic domains – e.g. the math and number crunching. As for the MatLab piece, I assume it is just a matter of finding the right math libraries and graphing libraries.

    Unfortunately I don’t have any reccomendations for mathematical .NET libraries.

  38. Thanks for Your answer. Could You recomend somebody I could turn to for answer?

  39. Tim says:

    I don’t understand Alex’s complaint about minimal type checking. As far as I can see, F# has quite strict type checking at compile time (much stricter than the C family of languages, for example). Maybe it’s not obvious from the tutorial, because you don’t have to /tell/ F# the type of an identifier if F# can unambiguously infer it.

  40. Tim says:

    Jason, you do realise that "let" in F# is completely unrelated to "let" in BASIC, don’t you? The F# equivalent to BASIC’s

       LET A = 5


       a <- 5

    No sign of a "let". In F#, "let" means something quite different, that I don’t think has a direct equivalent in non-functional languages (I suppose it has /some/ similarity to "&" in C++, because it’s defining a sort of alias).

  41. Dustin Boyd says:

    For those that still don’t understand the [1 .. 2 .. 10] bit, it reminds me a bit of the FOR statement when used with the /L option:

    FOR /L (start, step, end) DO action

    Although I don’t have much knowledge of the .NET library, it is reasonable to infer that "List.map square [1 .. 2 .. 10]" creates a list by mapping its elements to the result of calling square with arguments 1, 3, 5, 7 and 9 (because the step value is 2, and the constraints specified 1 to 10 inclusive).  The end result is that we end up with with the squares of the numbers above.  It also reminds me of list comprehensions in Python:

    >>> [square(i) for i in range(1, 11, 2)]

    [1, 9, 25, 49, 81]

    Of course, in Python, the range function excludes the upper limit, so 11 needs to be used rather than 10.

    I love these types of languages.  They can get so much done with such little code!

  42. F# you can even write XBox games using XNA.

    I tried a small demo, it works very nicely.

    Selami Ozlu

  43. wised says:

    Stupid Microsoft, this is just another VBscript.

    Stupid VBstscript, certainly stuoid F# again.

  44. Monty says:

    Just Learn Python instead. Get all the Dynamic stuff without the .net Framework. Why would you try to do dynamic stuff in the CLR?

    I tried doing a recursive lambda once in c#. nightmare and it doesn’t work.

    The new stuff on DLR looks interesting though, although I am thinking of jumping ship to Python as it does all that I want and then some. Who needs stupid acronyms like LINQ when you got list comprehensions.

    If you really want the functional style then go Haskell, the only one that doesn’t cause a stack overflow as far as I can tell.

  45. Craig says:

    It would be nice to see a better example of the advantages of F# over C#.  As a C# developer, I agree with some others that it just looks like some awkward syntax and easy way to code in more errors so far.

    Can you give an example of something F# can do that C# can’t?

  46. Why Caml (instead of – say – Haskell, Standard ML, or even Erlang)?

    Just curious – I don’t consider this decision to be bad, after all…

  47. renu says:

    @MarcinK – Haskell is pure FP, no OO construct.  Ocaml has the OO stuff that F# also supports.

  48. F# is the new kid on the block in terms of .NET languages.&#160; Currently in CTP form , it will be one

  49. John says:

    F# has its roots in a programming language called OCaml, C# has its roots in a programming language called Java, Garbage Collection has its roots in Lisp, etc.

  50. John II says:

    So why all this efforts to re-invent the wheel?

  51. Surendra Sharma says:

    Good Article. But why I used F#, if I already have C#? If possible make a comparison among F#, C# and Java. Only for mathematical calculation, I will never usr F#.

  52. Terry says:

    Why would you use F# …….. ?

    Anyone who thinks that this is a) like Fortran (trust me it isnt) or b) just for calculation so wont use it either hasnt gone far enough yet or has their head wedged where the sun dont shine 🙂

    May I point you to the excellent PDC demo (about 78 minutes) go to the F# research page click on getting started and about halfway down you will see a thumbnail marked demo – run that demo and be amazed.

  53. balboos says:

    It’s nice to have had someone write a tutorial, but (IMHO) this one just leaves out too many concepts for a part-one.  It’s borders on a turn-off, for what is basically a lot of clutter.

    It’s not that I’m particularly dim-witted, having followed a language use path of FORTRAN->assembly->C->C++ , and C# when necessary (because MS didn’t see fit to include the functionality in C++).  The [1..2..10] was (to me), an obvious syntax, given the results.

    I just think that a tutorial should <i>teach more and extol less</i>.  Again, this is an IMHO.

  54. Rod Wue says:

    I read these comments and I wonder about if some of you even read anything about F# before you commented. I’m certainly not a F# evangelist as I only really started looking at it more closely in the past few weeks.

    It’s interesting how many of the commenters don’t understand "side effects" They keep asking what good is F#? WHy would I use this.. Etc. Etc. Perhaps you should watch the Anders interview about C# 4.0 they go off on a tangent that might help you understand.

  55. @Eric Eilebrecht

    "Note that the hard part is declaring the sequence (which of course would be easier if there was an "Enumerable.Sequence" method or somesuch)"

    You could use Enumerable.Range

  56. BAIJUMAX says:

    Nice Intro .

    I’m new to F#, enjoyed reading this article.

    F# looks similar to Matlab programming (.M code) .  

  57. Next Chicago ALT.NET meeting will bring a practical look at F#, showing that it does not need to be seen

  58. Bui Viet Duc says:

    I did not try F#

    But based on this introduction, I think F# borrows the idea of Prolog

  59. person-b says:

    @Bui Viet Duc:

    F# is part of a family of so-called "functional languages". Examples of these languages are Haskell, LISP, Scheme. They also borrow some concepts from languages such as Prolog. They don’t, however, copy their core ideals and syntax from Prolog.

  60. 第一篇,从零开始编写我们的第一个F#程序。 什么是F#,我为何要学它? F#是一种.NET平台上的 函数式编程 语言。就像C#和VB.NET,F#可以利用.NET的核心类库,如 WPF , WCF ,

  61. raghu says:

    Great article. Will definitely be reading up more on F#.

    Just wish that MS would offer lisp as well.

  62. ming says:

    I suspect for a beginner this might not be the most friendy introduction…

  63. Jeba Singh says:

    It’s a great article to know about F#.

Comments are closed.

Skip to main content