English for F# Developers

Vocabulary for developers working in F# — discriminated unions, the pipe operator, type providers, and the functional-first vocabulary that .NET teams need when moving beyond C#.

F# runs on the same runtime as C# but is discussed with a different vocabulary, because it’s functional-first rather than object-first. Teams moving between the two languages often default to C# terms that don’t map cleanly, which is where most F# miscommunication actually starts.

Key Vocabulary

Discriminated union (DU) — F#‘s sum type, representing a value that is exactly one of several named cases, each of which can carry its own data, used to make invalid states unrepresentable rather than relying on inheritance hierarchies or nullable fields. “Model the payment result as a discriminated union with Success and Failure cases instead of a class with a nullable error field — now the compiler forces every caller to handle both cases explicitly, there’s no way to forget the failure branch.”

Pipe operator (|>) — F#‘s forward-pipe operator that passes the result of an expression as the last argument to the next function, letting a sequence of transformations read top-to-bottom in the order they actually happen, rather than nested inside-out. “Rewrite this as a pipeline with the pipe operator — data |> filterValid |> sortByDate |> take 10 reads in the exact order these transformations happen, instead of nesting three function calls that you have to read from the inside out.”

Type provider — an F#-specific compile-time mechanism that generates types automatically from an external data source, like a database schema, a JSON sample, or a CSV file, giving you compile-time-checked access to that external shape without hand-writing model classes. “We didn’t hand-write these thirty model classes — a type provider generated them at compile time directly from the JSON schema, so if the API’s shape changes, the build itself fails instead of a runtime deserialization error.”

Exhaustive pattern matching — F#‘s compiler check that a match expression covers every case of a discriminated union, issuing a warning (often treated as an error) when a case is missing, catching a class of bugs statically that many languages only catch at runtime, if at all. “Add the new Refunded case to that discriminated union, and every match expression across the codebase handling OrderStatus will now warn as incomplete until it’s updated — that’s exhaustive pattern matching doing exactly its job.”

Computation expression — F#‘s syntax for building custom control-flow blocks (like async { } or option { }) that desugar into chained function calls, used to make monadic or effectful code read in an imperative, linear style. “That async { } block isn’t special language syntax bolted on for async — it’s a computation expression, and the same mechanism is available for building your own custom control flow, like a result { } block for railway-oriented error handling.”

Common Phrases

  • “Is this modeled as a discriminated union, or are we tracking state with a class and some optional fields?”
  • “Would this read more clearly as a pipeline using the pipe operator?”
  • “Is this type coming from a type provider, or is it hand-written and could drift from the actual schema?”
  • “Is this match expression exhaustive, or is there a wildcard case swallowing something we should handle explicitly?”
  • “Is that a computation expression, or plain nested function calls?”

Example Sentences

Explaining a design decision in review: “I modeled the API response as a discriminated union with Ok, NotFound, and ServerError cases instead of a status code plus a nullable body — now the compiler won’t let a caller forget to handle the error cases.”

Reviewing code for readability: “This works, but nesting five function calls makes it hard to read top-to-bottom. Rewrite it with the pipe operator so each transformation step reads in the order it actually executes.”

Explaining a compile-time safety win: “We’re using a type provider against the actual production schema, so when a column got renamed last sprint, this failed at compile time immediately — instead of failing silently in a hand-written model that nobody remembered to update.”

Professional Tips

  • Reach for a discriminated union whenever a value can genuinely only be one of several distinct shapes — it’s the idiomatic F# alternative to inheritance or nullable-field modeling, and reviewers will expect it for domain modeling.
  • Use the pipe operator to express any multi-step transformation — it’s not just stylistic; a pipeline reads in execution order, which measurably reduces review time compared to deeply nested calls.
  • Prefer a type provider over hand-written models whenever a stable external schema is available — it turns a schema drift into a compile-time failure instead of a runtime surprise.
  • Never suppress an exhaustive pattern matching warning with a blanket wildcard unless missing cases should genuinely be silently ignored — that’s a decision worth making explicit and reviewing, not a default.
  • Reach for a computation expression when you’re repeatedly hand-rolling the same effectful control-flow pattern — it’s F#‘s tool for making that pattern reusable and readable, not just for async code.

Practice Exercise

  1. Explain why modeling state as a discriminated union can prevent invalid-state bugs.
  2. Describe how the pipe operator changes the readability of a multi-step transformation.
  3. Write a sentence explaining what a type provider does and why it catches schema drift at compile time.

Frequently Asked Questions

What English level do I need to read "English for F# Developers"?

This article is tagged Advanced. If you find the vocabulary difficult, start with a related Vocabulary vocabulary exercise first, then come back — technical reading gets much easier once the core terms feel familiar.

Is this article free to read?

Yes. Every article on CoderSlingo, including this one, is free to read with no account, sign-up, or paywall.

How is reading this article different from doing an exercise?

Articles like this one explain concepts and vocabulary in context through prose, while exercises are interactive drills — fill-in-the-blank, matching, and multiple-choice — that test and reinforce specific terms. Reading builds understanding; exercises build recall.