United Kingdom: +44 (0)208 088 8978

F# 9 wrap up

In this post, Matt wraps up our series on F# 9, briefly touching the topics that haven't been covered so far.

We're hiring Software Developers

Click here to find out more

This is the last post in our series about F# 9. Check out the full series overview for more posts about shiny new F# features!

F# 9 has a bunch of cool new features. In dedicated posts, we've covered collection functions for random sampling and shuffling, .Is* properties for discriminated unions, and nullable reference type support. In this final post, wrapping up the series, we'll take a whistle-stop tour through some other highlights.

Partial active patterns returning booleans

You previously had to return an Option from active pattern functions. Now you can use bools for simple cases.

// Had to return an option before.
let (|Adult|_|) person = if person.Age >= 18 then Some() else None

// Now a boolean is valid.
let (|Adult|_|) person = person.Age >= 18

#help in fsi

New to F# and want to experiment in F# interactive? Now you can use the #help directive to get quick access to documentation you as you learn.

#help Option.bind;;

Description:
bind f inp evaluates to match inp with None -> None | Some x -> f x

Parameters:
- binder: A function that takes the value of type T from an option and transforms it into
 an option containing a value of type U.
- option: The input option.
Returns:
An option of the output type of the binder.

Examples:
let tryParse (input: string) =
    match System.Int32.TryParse input with
    | true, v -> Some v
    | false, _ -> None
None |> Option.bind tryParse // evaluates to None
Some "42" |> Option.bind tryParse // evaluates to Some 42
Some "Forty-two" |> Option.bind tryParse // evaluates to None

Full name: Microsoft.FSharp.Core.OptionModule.bind
Assembly: FSharp.Core.dll

TailCall attribute warnings

The TailCall attribute was added in .NET 8. You now get a warning if you use it on something that's not a recursive function, since it doesn't make any sense there!

Attribute target enforcement

There are other non-standard attributes, such as attributes for test libraries, that only make sense on certain language elements. For example, some test library attributes only make sense on functions, not on modules and their definition includes that information. The F# compiler will now enforce that, with errors if attributes are used on elements of the wrong type.

But wait, there's more!

We've covered the major new features, but make sure to check out the official What's New in F# 9 post for more details. There are developer productivity improvements including better parsing of malformed code (for better syntax highlighting) and improved diagnostic messages. F# 9 also brings performance improvements that you can benefit from just by using F# 9, without changing your code!

We're glad to see F#—which is already a fantastic programming language—getting so much love, and are excited to see it go from strength to strength in 2025 and beyond 🚀