F# for C#/Java developers — Mission
Sections
Reading settings
No voice for this language in this browser.
More voices
Code and English terms
Off: the page’s voice reads everything, with no pause between two voices.
No voice for this language in this browser.
More voices
More voices: Microsoft Edge has natural online voices, and Windows (Settings › Time & language › Speech), macOS and Android install others.
Why this course
Section titled “Why this course”You write C# or Java. You have used lambdas, LINQ or streams, records, maybe switch expressions with patterns. F# takes those ideas, which C# and Java borrowed from functional languages over the last fifteen years, and makes them the default: values that don’t change, functions that return values instead of changing state, types that describe every case of your data, and a compiler that checks that you handled all of them.
F# runs on .NET, calls every .NET library, and compiles to the same intermediate language as C#. You don’t have to leave your ecosystem to learn it, and what you learn changes how you write C#.
This course uses the current versions: F# 10, which ships with .NET 10, released in November 2025.
Real code: TARS and Guitar Alchemist
Section titled “Real code: TARS and Guitar Alchemist”The examples come from two public F# code bases, pinned on a commit so that the links keep pointing at the code the lessons describe:
- TARS, an F# agent framework (reasoning, multi-agent workflows, probabilistic grammars), at commit
87464ce. Its active code lives inv2/: the lessons only cite projects that its solutionv2/Tars.slnbuilds and that its CI tests. - Guitar Alchemist (GA), a music theory application written mostly in C#, whose music DSL, parsers, configuration and language server are in F#, at commit
32f143c.
When an extract of GA compiles on its own, the course keeps a copy of the file in code/fsharp/external/ga (GA is under the MIT license) and runs it. TARS has no license file, so its code is linked and quoted, and reproduced in a few lines only where a behavior needs to be shown. What the lessons find in these repositories (a bug, dead code, a script that doesn’t run) goes in the journal.
How the lessons work
Section titled “How the lessons work”Each lesson starts from what you would write in C# (and in Java when it differs), then:
- the F# way, with a short script and the output it really printed;
- the compiler’s view: the errors and warnings you will meet, with their exact message;
- real code from TARS or GA that uses the notion;
- exercises, with a solution under Solution: try first, then open it.
By the end of this course, I will be able to
Section titled “By the end of this course, I will be able to”- run F# scripts and F# Interactive, and organize an F# project whose files compile in order;
- model a domain with records, discriminated unions and options, so that invalid states don’t compile;
- write functions that compose, with pipelines, partial application and exhaustive pattern matching;
- handle errors with
Result, and write and read computation expressions, including my own; - test F# code with xUnit, FsCheck and Expecto, and parse text with FParsec;
- measure and reduce allocations, and choose between
Async,TaskandMailboxProcessor; - read and extend a real F# code base, and publish an F# library that C# code consumes comfortably.
Outline
Section titled “Outline”| # | Lesson | Notions | Real code |
|---|---|---|---|
| Beginner | |||
| 1 | Scripts, F# Interactive and projects | dotnet fsi, .fsx scripts, printfn, #r "nuget:", indentation, the file order of a .fsproj |
GA’s GA.Business.DSL.fsproj and Scripts/ModesConfig.fsx, TARS’s Tars.Core.fsproj |
| 2 | Values, functions and type inference | let, immutability, mutable, inference, currying, partial application, |> and >>, expressions everywhere |
GA’s HarmonicTransformationService, TARS’s TextNormalizer |
| 3 | Tuples, records, unions and options | tuples, records and with, discriminated unions, Option, single-case unions, RequireQualifiedAccess |
GA’s ChordAst, TARS’s Domain.fs and Primitives.fs |
| 4 | Pattern matching | match, guards, or-patterns, list and record patterns, exhaustiveness warnings |
GA’s ChordRenderer, ChordParser and BinObj.fsx, TARS’s AgentWorkflow.fs |
| 5 | Lists, arrays and sequences | List, Array and Seq modules, pipelines next to LINQ and streams, laziness |
|
| 6 | Modules, namespaces and project organization | modules, namespaces, private and internal, signature files |
|
| Intermediate | |||
| 7 | Errors with Result |
railway-oriented programming, Result next to exceptions |
|
| 8 | Computation expressions — a parser for a DSL | seq, async, task, builders, Bind, Return, a parser CE and explicit end-of-input |
GA’s music DSL |
| 9 | Objects in F# | classes, interfaces, object expressions, calling C# libraries | |
| 10 | Testing | xUnit, FsCheck property-based tests, Expecto | |
| 11 | Parsers | FParsec and hand-written combinators | GA’s music DSL |
| 12 | Modeling a domain | units of measure, phantom types, making illegal states unrepresentable | TARS’s Budget |
| Advanced and expert | |||
| 13 | Custom computation expressions | builders, let! and and!, what the compiler generates |
TARS’s AgentWorkflow |
| 14 | Type providers — typed data from a sample | erased and generative providers, CSV and JSON inference, schema stability | FSharp.Data |
| 15 | Performance | structs, inline, Span, voption, allocations measured with BenchmarkDotNet |
|
| 16 | Concurrency | MailboxProcessor, Async next to Task, channels |
|
| 17 | Metaprogramming | Myriad, FSharp.Compiler.Service | GA’s F# Interactive session pool |
| 18 | Tooling | a language server in F#, Fantomas, analyzers | GA’s GaMusicTheoryLsp |
| 19 | Architecture of a real F# application | a guided reading of TARS | TARS |
| 20 | Publishing an F# library for C# | API design, [<CompiledName>], options and unions seen from C# |
|
| — | Journal |
Lessons 9–13 and 15–20 are planned and not written yet.
Prerequisites
Section titled “Prerequisites”- You program in C# or Java. No functional programming experience is needed.
- The .NET 10 SDK, on Windows, Linux (or WSL) or macOS. Lesson 1 checks the installation; the C# for beginners course details it for each OS.
- An editor with F# support: Visual Studio Code with the Ionide extension, JetBrains Rider, or Visual Studio on Windows.
Related courses
Section titled “Related courses”- Advanced C# covers what happens under .NET: memory, the garbage collector,
asyncand measured performance. This course links to it rather than repeating it; lessons 15 and 16 build on it. - Rust for C#/Java developers meets the same ideas from another side: enums and
match,OptionandResult.
Resources
Section titled “Resources”- F# documentation, with its tour of F# and language reference.
- What’s new in F# 10.
- FSharp.Core API reference: the
List,Option,Resultmodules and the rest of the core library. - The F# language specification and the design RFCs in fsharp/fslang-design.
- dotnet/fsharp: the compiler, FSharp.Core and F# Interactive.
- F# style guide and F# coding conventions.