Cloud Parts

F#

A functional-first language from the ML family that runs on .NET, with type inference, immutable data by default and computation expressions.

What it is
Programming languages (run on a virtual machine),Functional programming
Type
Open source
Made by
Microsoft and the F# Software Foundation
License
MIT
Facts checked
8 October 2026

What it is

F# is a strongly typed, functional-first language descended from ML and OCaml. Types are inferred, so most code has no type annotations, and values, records and discriminated unions are immutable by default. Pattern matching over a union makes the compiler check that every case is handled. Classes and interfaces are there too, for code that needs objects.

It compiles to the same intermediate language as C#, and its types are .NET types: an F# string is a .NET string, a .NET class can be used from F#, and an F# function can be called from C#. There is no translation layer in between.

Computation expressions are F#’s general syntax for sequencing a kind of computation. Inside a builder such as async { }, task { } or seq { }, let! and return mean whatever that builder defines, which covers asynchronous code, sequences, and any monad-like type you write yourself. F#’s async { } arrived in 2007, and its designer counts C# 5’s async/await among the C# features heavily influenced by F#.

Why teams pick it

  • Succinct code: type inference, immutable records and unions, and pipelines (|>) keep programs short without losing static types
  • The compiler checks that pattern matches cover every case of a union, which makes illegal states hard to express
  • Two-way interoperability with C# and every .NET library, with no marshalling
  • Computation expressions give one syntax for async code, sequences and custom workflows

Watch out for

  • F# is bound to .NET: it gets whatever the runtime offers, and its designer won’t add features such as type classes or higher-kinded types unless C# gets a matching one
  • Two async styles coexist: async { } starts only when run and passes cancellation implicitly, while task { } starts immediately and needs a token passed by hand

Alternatives

What all run on a virtual machine have in common →

How it fits with other technologies

A discriminated union, a pipeline and an `async` computation expression · fsharp

type Shape =
    | Circle of radius: float
    | Rect of width: float * height: float

let area shape =
    match shape with
    | Circle r -> System.Math.PI * r * r
    | Rect (w, h) -> w * h

[ Circle 1.0; Rect (2.0, 3.0) ]
|> List.sumBy area
|> printfn "%.2f"   // 9.14

// A computation expression: `async { }` sequences asynchronous steps
let answer = async {
    do! Async.Sleep 100
    return 42
}

printfn "%d" (Async.RunSynchronously answer)   // 42

See it in a real stack

No architecture uses F# yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2002–2020

In 1997, partly as a response to Java, Microsoft began the projects that became .NET and C#. Researchers at Microsoft Research in Cambridge, who came from strongly typed functional programming, joined the effort to bring many languages to .NET. Don Syme worked on .NET generics, which shipped with C# 2.0, and then on a language of his own.

His idea was simple: bring OCaml to .NET and .NET to OCaml. He wrote the first lines of F# in December 2001 and made a near-silent first release in June 2002. F# 1.0 was declared in January 2005 and demonstrated at Microsoft Research’s TechFest that March. Over the next years it gained pipelines, active patterns, async (2007) and computation expressions.

Microsoft turned the research language into a product: Visual F# 2.0 shipped with Visual Studio 2010 in April 2010. That November Microsoft released the source under Apache 2.0, and from 2014 it accepted outside contributions. The same year Syme, Tomas Petricek and Phil Trelford started the F# Software Foundation, through which the language design process and RFCs now run.

Why it’s built this way

Be a .NET language first, OCaml second
Syme’s most important decision was that .NET types are F# types, with no translation or marshalling. It meant F# often had to accept whatever .NET did, but it guaranteed two-way interop, and it was the main reason to design a new language rather than map an existing one onto .NET.
Start from OCaml, but leave out functors
Caml Light and OCaml gave a proven, pragmatic core with type inference. OCaml’s functorial module system was left out of the design.
No Haskell-style type classes
Type classes would add a new kind of top-level declaration that clashed with object programming, and their usual implementation can make small code changes cause big performance swings. F# used inlined functions with statically resolved type parameters instead.
Generalize async into computation expressions
Multi-core machines and web requests made concurrency central, and operating-system threads on Windows were too expensive to use one per task. async { } let non-blocking code read sequentially, and the same notation, drawing on Haskell’s do notation and comprehensions, was opened up to any builder type.

Timeline

  1. 2002

    First release from Microsoft Research Cambridge, in June

  2. 2005

    F# 1.0 declared in January

  3. 2007

    Asynchronous workflows (async { }) announced in October

  4. 2010

    Visual F# 2.0 ships with Visual Studio 2010; source released under Apache 2.0 in November

  5. 2012

    F# 3.0 adds type providers

  6. 2014

    Microsoft accepts outside contributions; the F# Software Foundation is founded

  7. 2020

    Syme’s “The Early History of F#” published at HOPL IV

Sources6 · facts checked 8 October 2026

Improve this page on GitHub