F# is built and run with the .NET SDK. The compiler is fsc (invoked by dotnet build), the interactive tool is dotnet fsi, and projects are described by .fsproj files.
The dotnet command line
// in a shell, not F#:
// dotnet new console -lang "F#" -o src/App create a console project
// dotnet new classlib -lang "F#" -o src/Library create a library
// dotnet new sln -o MySolution create a solution
// dotnet add src/App/App.fsproj reference src/Library/Library.fsproj
// dotnet build compile (invokes the F# compiler)
// dotnet run build and run
// dotnet fsi F# Interactive: a read-eval-print loop
// dotnet fsi Script.fsx hello world run a script with arguments
A project file lists the sources in compilation order and the packages:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<WarnOn>3390,3388</WarnOn>
<OtherFlags>--warnon:FS3559</OtherFlags>
</PropertyGroup>
<ItemGroup>
<Compile Include="Types.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Data" Version="6.4.0" />
</ItemGroup>
</Project>
Compile items is the compilation order.The project file is covered with the build files; what matters here is that the order of Compile items is the file order of the file structure page, that LangVersion selects the language version (latest, preview, 10 …), that Nullable turns on nullness checking (and defines NULLABLE), that WarnOn takes warning numbers (comma-separated, once), and that OtherFlags carries any other compiler option.
Compiler options
The options the documentation lists for the compiler (dotnet build passes them for a project):
| Option | What it does |
|---|---|
--define:symbol, -d:symbol | defines a symbol for #if |
--reference:file, -r:file, --lib:dir (-I:dir) | references an assembly; adds a search directory |
--out:file (-o), -a file.fs | names the output; builds a library |
--sig:file, --allsigs | writes a signature file for the assembly, or one for each source file |
--doc:file | writes the XML documentation (/// comments) |
--nowarn:list, --warnon:list, --warn:level | turns warnings off or on; sets the warning level (0 to 5, default 3) |
--mlcompatibility | ignores the warnings of the OCaml-compatible features |
--crossoptimize, --always-inline, --reflectionfree | optimisation and code-generation switches (F# 11 added the last two) |
--standalone, --staticlink:assembly, --noframework, --simpleresolution | how references are bundled and resolved |
--keyfile, --keycontainer, --platform, --baseaddress, --subsystemversion, --win32res, --win32manifest, --nowin32manifest, --resource, --linkresource | assembly signing, target and resources |
--pdb, --pathmap, --quotations-debug, --fullpaths | debugging and path reporting |
--codepage, --utf8output, --preferreduilang, --consolecolors, --nologo, --times, --help | text encoding, messages and timing |
Language support depends on the SDK’s feature band: with the .NET 11.0.100 SDK the F# 11.2 features need --langversion:preview, and 11.2 is planned as the default for SDK 11.0.200. The non-strict indentation mode has been removed, including in earlier numbered language modes.
F# Interactive and scripts
dotnet fsi reads F# from the console (an entry ends with ;;) or runs a script file, with the directives of the directives page. Output of values is printed with %A style formatting that can be customised with fsi.AddPrinter and fsi.AddPrintTransformer. A script can read its arguments from fsi.CommandLineArgs. Notebooks (Polyglot Notebooks, Jupyter with the .NET kernel) run F# cells in the same way.
Editors
- Visual Studio has full F# support (project system, debugger, F# Interactive window).
- Visual Studio Code with the Ionide extension, whose language server is FsAutoComplete, which is built on the F# compiler’s services.
- Other editors that speak the language server protocol can use FsAutoComplete too; JetBrains Rider and other IDEs have F# support of their own (not described here).
Community tools
| Tool | What it does | Files it uses |
|---|---|---|
| Fantomas | the F# code formatter; dotnet tool install fantomas, then dotnet fantomas on files or folders | .editorconfig with fsharp_* settings (for example fsharp_keep_max_number_of_blank_lines) |
| FAKE | F# build automation: the build is an F# script run with dotnet fake build after dotnet tool restore | build.fsx |
| Paket | a dependency manager for .NET that sits beside or replaces NuGet references | paket.dependencies (sources and nuget lines), paket.lock, paket.references |
| FSharpLint | a code checker | a settings file |
| FSharp.Compiler.Service | the compiler as a library (parsing, checking, tokenising), used by the tools above | — |
The documentation’s page on development tools names Fantomas, FSharpLint and FAKE. The Paket file names above come from the Paket repository read for this site (its own paket.dependencies starts with a source line, then option lines such as framework: and package lines nuget Name version-constraint).
Not described
Known, not yet covered
- Reference: the full F# Interactive options table, MSBuild properties of
Microsoft.FSharp.Targets, test frameworks (xUnit, NUnit, Expecto), the Ionide settings, the Fantomas settings list, FSharpLint rules, FAKE modules and Paket commands, and notebooks are only named. The.fsproj,.slnand MSBuild files belong to other pages of this site. - Reference: the project example was written for this page (version numbers are examples) and not built; no .NET SDK was available here.
See also
- Directives and conditional compilation –
#r,#load,#nowarn - Versions and history – the language versions