United Kingdom: +44 (0)208 088 8978

F# 8: accessing properties without fuss

One of the new features of F# 8 is a shorthand for accessing properties. In this blog post, we have a look at this wonderfully clean notation.

We're hiring Software Developers

Click here to find out more

This post is part of our F#8 series, in which we'll be digging into a few of the best features in the latest version of the language.

Lambda functions are a great tool that allow us to write functions on the fly wherever we need them. F#'s fun <arg> -> syntax provides a brief, clear notation for these functions. But what if even a Lambda function is too much? Among other great features, F# 8 introduces the _.Member shorthand, which lets you access members in just two characters!

Imagine you have a list of people that you want to transform to a list of birth years:

type Person =
    {
        BirthYear: int
        Name: string
    }
    member this.Age year  =
        year - this.BirthYear

let people = [
    { BirthYear = 1964; Name = "Ben" }
    { BirthYear = 1992; Name = "Anne" }
    { BirthYear = 2013; Name = "John" }
    { BirthYear = 1993; Name = "Steve" }
    { BirthYear = 1964; Name = "Lynn" }
    { BirthYear = 1993; Name = "Jeff" }
    { BirthYear = 2012; Name = "Jule" }
]

Before F# 8 we'd use a Lambda function:

people
|> List.map (fun person -> person.BirthYear)
//int list = [1964; 1992; 2013; 1993; 1964; 1993; 2012]

While writing this quickly became an automatism for me, I do feel there are two downsides to this. Firstly, it does not read as simply as it could - before you see what you are accessing, have to go through boilerplate code that enables to access the property. Secondly, you are forced to name something in a miniscule scope. It might be a bit pedantic, but with naming being a major cause of headache amongst developers, I'd rather see that gone.

Shorthand lambda syntax to the rescue

Thanks to an issue that had been open since November 2016, we now have the _.Property shorthand:

people
|> List.map _.BirthYear
//int list = [1964; 1992; 2013; 1993; 1964; 1993; 2012]

This does not just work for properties, but also for methods:

people
|> List.map _.Age(2024)
//int list = [60; 32; 11; 31; 60; 31; 12]

The shorthand works for everything that can be used in a Lambda function. For example, let's give it a go with an anonymous record:

let appleTree =
    Some {| Apples = 50 |}

appleTree
|> Option.map _.Apples
// int option = Some 50

Limitations

There is one case where anonymous records don't work: you can not use it in the same scope as a discarded (_) variable:

let getName myPersonOption _ =
    myPersonOption
    |> Option.map _.Name

This will result in a compiler warning: The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope

In addition, shorthand lambda syntax is specific designed for member access - you cannot use it within the context of a more complex expression.

Conclusion

As you can see, the lambda shorthand is a great addition to the F# language that makes your code cleaner and more readable. Thanks to all the developers that contributed to F# 8!