F# (pronounced F sharp) is a general-purpose, high-level, strongly typed, functional-first programming language that encompasses functional, imperative, and object-oriented programming methods. It is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but can also generate JavaScript and graphics processing unit (GPU) code.
F# is developed by the F# Software Foundation, Microsoft and open contributors. An open source, cross-platform compiler for F# is available from the F# Software Foundation. F# is a fully supported language in Visual Studio and JetBrains Rider. Plug-ins supporting F# exist for many widely used editors including Visual Studio Code, Vim, and Emacs.
F# is a member of the ML language family and originated as a .NET Framework implementation of a core of the programming language OCaml. It has also been influenced by C#, Python, Haskell, Scala and Erlang.
History
Versions F#version Language specification Date Platforms Runtime 1.x May 2005Windows.NET 1.0 - 3.5 2.0 August 2010 April 2010Linux, macOS, Windows .NET 2.0 - 4.0, Mono 3.0 November 2012 August 2012Linux, macOS, Windows;JavaScript, GPU.NET 2.0 - 4.5, Mono 3.1 November 2013 October 2013Linux, macOS, Windows;JavaScript, GPU.NET 2.0 - 4.5, Mono 4.0 January 2016 July 2015 4.1 May 2018March 2017Linux, macOS, Windows, JavaScript, GPU.NET 3.5 - 4.6.2, .NET, Mono 4.5August 2018Linux, macOS, Windows, JavaScript, GPU .NET 4.5 - 4.7.2, .NET Core SDK 2.1.400 4.6March 2019Linux, macOS, Windows, JavaScript, GPU .NET 4.5 - 4.7.2, .NET Core SDK 2.2.300 4.7September 2019Linux, macOS, Windows, JavaScript, GPU .NET 4.5 - 4.8, .NET Core SDK 3.0.100 5.0November 2020Linux, macOS, Windows, JavaScript, GPU .NET SDK 5.0.100 6.0November 2021Linux, macOS, Windows, JavaScript, GPU .NET SDK 6.0.100 7.0November 2022Linux, macOS, Windows, JavaScript, GPU .NET SDK 7.0.100 8.0November 2023Linux, macOS, Windows, JavaScript, GPU .NET SDK 8.0.100 9.0November 2024Linux, macOS, Windows, JavaScript, GPU .NET SDK 9.0.010.0November 2025Linux, macOS, Windows, JavaScript, GPU.NET SDK 10.0.0
Language evolution F# uses an open development and engineering process. The language evolution process is managed by Don Syme from Microsoft Research as the benevolent dictator for life (BDFL) for the language design, together with the F# Software Foundation. Earlier versions of the F# language were designed by Microsoft and Microsoft Research using a closed development process.
F# was first included in Visual Studio in the 2010 edition, at the same level as Visual Basic (.NET) and C# (albeit as an option), and remains in all later editions, thus making the language widely available and well-supported.
F# originates from Microsoft Research, Cambridge, UK. The language was originally designed and implemented by Don Syme, according to whom in the fsharp team, they say the F is for "Fun". Andrew Kennedy contributed to the design of units of measure. The Visual F# Tools for Visual Studio are developed by Microsoft. The F# Software Foundation developed the F# open-source compiler and tools, incorporating the open-source compiler implementation provided by the Microsoft Visual F# Tools team.
+ Summary of versions F#version Features added 1.0 Functional programming Discriminated unions Records Tuples Pattern matching Type abbreviations Object-oriented programming Structs Signature files Scripting files Imperative programming Modules (no functors) Nested modules .NET interoperability 2.0 Active patterns Units of measure Sequence expressions Asynchronous programming Agent programming Extension members Named arguments Optional arguments Array slicing Quotations Native interoperability Computation expressions 3.0 Type providers LINQ query expressions CLIMutable attribute Triple-quoted strings Auto-properties Provided units-of-measure 3.1 Named union type fields Extensions to array slicing Type inference enhancements 4.0 Printf on unitized values Extension property initializers Non-null provided types Primary constructors as functions Static parameters for provided methods Printf interpolation Extended #if grammar Tailcall attribute Multiple interface instantiations Optional type args Params dictionaries 4.1 Struct tuples which inter-operate with C# tuples Struct annotations for Records Struct annotations for Single-case Discriminated Unions Underscores in numeric literals Caller info argument attributes Result type and some basic Result functions Mutually referential types and modules within the same file Implicit "Module" syntax on modules with shared name as type Byref returns, supporting consuming C# ref-returning methods Error message improvements Support for 'fixed' 4.5 Versioning alignment of binary, package, and language Support for 'Span<T>' and related types Ability to produce 'byref' returns The 'voidptr' type The 'inref<'T>' and 'outref<'T>' types to represent readonly and write-only 'byref's 'IsByRefLike' structs 'IsReadOnly' structs Extension method support for 'byref<'T>'/'inref<'T>'/'outref<'T>' 'match!' keyword in computation expressions Relaxed upcast with 'yield' in F# seq/list/array expressions Relaxed indentation with list and array expressions Enumeration cases emitted as public 4.6 Anonymous record types 4.7 Implicit yields No more required double underscore Indentation relaxations for parameters passed to constructors and static methods 'nameof' function Open static classes 5.0 FSharp.Core now targets netstandard2.0 only Package references in F# scripts Support for Jupyter, nteract, and VSCode Notebooks String Interpolation Support for nameof Open Type declarations Enhanced Slicing F# quotations improvements Applicative Computation Expressions Improved stack traces in F# async and other computation expressions Improved .NET interop Improved Map and Set performance in FSharp.Core Improved compiler performance Improved compiler analysis for library authors 6.0 Tasks Simpler indexing Augments to "active patterns" Overloaded custom operations in computation expressions "as" patterns Indentation syntax revisions More implicit conversions More implicit upcast conversions Implicit integer conversions First-class support for .NET-style implicit conversions Optional warnings for implicit conversions Formatting for binary numbers Discards on use bindings InlineIfLambda optimizer directive Resumable code More collection functions Map has Keys and Values More intrinsics for NativePtr More numeric types with unit annotations Informational warnings for rarely used symbolic operators 7.0 Static abstract members support in interfaces Making working with SRTPs (statically resolved type parameters) easier Required properties checking Init scope and init-only properties Reference assemblies support F# self-contained deployments & Native AOT Added support for N-d arrays up to rank 32. Result module functions parity with Option. Fixes in resumable state machines codegen for the tasks builds. Better codegen for compiler-generated side-effect-free property getters ARM64 platform-specific compiler and ARM64 target support in F# compiler. Dependency manager #r caching support Parallel type-checking and project-checking support (experimental, can be enabled via VS setting, or by tooling authors) Miscellaneous bugfixes and improvements. 8.0 _.Property shorthand for (fun x -> x.Property) Nested record field copy and update while! (while bang) feature Extended string interpolation syntax Use and compose string literals for printf and related functions Arithmetic operators in literals Type constraint intersection syntax Extended fixed binding Easier [<Extension>] method definition Static members in interfaces Static let in discriminated unions, records, structs, and types without primary constructors try-with within seq{}, [], and [||] collection expressions Recursive calls and yield! within exception handler Tail call attribute [<Struct>] unions can now have > 49 cases Strict indentation rules New diagnostics from the compiler Switches for compiler parallelization 9.0 Nullable reference types Discriminated union .Is* properties Partial active patterns can return bool instead of unit option Prefer extension methods to intrinsic properties when arguments are provided Empty-bodied computation expressions Hash directives are allowed to take non-string arguments Extended #help directive in fsi to show documentation in the REPL Allow #nowarn to support the FS prefix on error codes to disable warnings Warning about TailCall attribute on non-recursive functions or let-bound values Enforce attribute targets Updates to the standard library (FSharp.Core) Developer productivity improvements Performance improvements Improvements in tooling10.0 Scoped warning suppression Access modifiers on auto property accessors ValueOption optional parameters Tail-call support in computation expressions Typed bindings in computation expressions without parentheses Allow _ in use! bindings Rejecting pseudo-nested modules in types Deprecation warning for omitted seq Attribute target enforcement Support for and! in task expressions Better trimming by default Parallel compilation in preview Type subsumption cache
Language overview
Functional programming F# is a strongly typed functional-first language with a large number of capabilities that are normally found only in functional programming languages, while supporting object-oriented features available in C#. Together, these features allow F# programs to be written in a completely functional style and also allow functional and object-oriented styles to be mixed.
Examples of functional features are:
Everything is an expression Type inference (using Hindley–Milner type inference) Functions as first-class citizens Anonymous functions with capturing semantics (i.e., closures) Immutable variables and objects Lazy evaluation support Higher-order functions Nested functions Currying Pattern matching Algebraic data types Tuples List comprehension Monad pattern support (called computation expressions) Tail call optimisation
F# is an expression-based language using eager evaluation and also in some instances lazy evaluation. Every statement in F#, including if expressions, try expressions and loops, is a composable expression with a static type. Functions and expressions that do not return any value have a return type of unit. F# uses the let keyword for binding values to a name. For example: let x = 3 + 4 binds the value 7 to the name x.
New types are defined using the type keyword. For functional programming, F# provides tuple, record, discriminated union, list, option, and result types. A tuple represents a set of n values, where n ≥ 0. The value n is called the arity of the tuple. A 3-tuple would be represented as (A, B, C), where A, B, and C are values of possibly different types. A tuple can be used to store values only when the number of values is known at design-time and stays constant during execution.
A record is a type where the data members are named. Here is an example of record definition: type R = { Name : string Age : int } Records can be created as . The with keyword is used to create a copy of a record, as in , which creates a new record by copying r and changing the value of the Name field (assuming the record created in the last example was named r).
A discriminated union type is a type-safe version of C unions. For example, type A = | UnionCaseX of string | UnionCaseY of int Values of the union type can correspond to either union case. The types of the values carried by each union case is included in the definition of each case.