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, whiletask { }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
What F# uses
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) // 42See 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
asyncinto 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’sdonotation and comprehensions, was opened up to any builder type.
Timeline
- 2002
First release from Microsoft Research Cambridge, in June
- 2005
F# 1.0 declared in January
- 2007
Asynchronous workflows (
async { }) announced in October - 2010
Visual F# 2.0 ships with Visual Studio 2010; source released under Apache 2.0 in November
- 2012
F# 3.0 adds type providers
- 2014
Microsoft accepts outside contributions; the F# Software Foundation is founded
- 2020
Syme’s “The Early History of F#” published at HOPL IV
Sources6 · facts checked 8 October 2026
- Microsoft Learn: What is F#
- Microsoft Learn: Computation expressions (F#)
- Microsoft Learn: Task expressions (F#), on starting immediately and cancellation
- Microsoft Learn: Managed execution process (F# among the compilers that target the CLR)
- Don Syme: The early history of F# (interop design, influence on C#, type classes)
- dotnet/fsharp license (MIT)