We’re excited to announce more updates to F# 5 which will go alongside .NET 5 preview 8! We’ve shipped various updates since the beginning of this year:
Today, we’re pleased to announce the completion of the F# 5 feature work. There is one minor enhancement planned for the .NET 5 RC, but other than that we are finished with F# 5! From this point forward, our journey to shipping F# 5 will be focused mostly on bug fixes and addressing feedback.
You can get the latest F# 5 in these ways
- Install the latest .NET 5 preview SDK
- Install .NET for Jupyter/nteract
- Install .NET for VSCode Notebooks
If you’re using Visual Studio on Windows, you’ll need both the .NET 5 preview SDK and Visual Studio Preview installed.
Using F# 5 preview
You can use F# 5 preview via the .NET 5 preview SDK, or through the .NET and Jupyter Notebooks support.
If you’re using the .NET 5 preview SDK, check out the sample repository which shows off some of what you can do with F# 5. You can play with each of the features there instead of starting from scratch.
If you’d rather use F# 5 in your own project, you’ll need to add a LangVersion
property with preview
as the value. It should look something like this:
Alternatively, if you’re using Jupyter Notebooks and want a more interactive experience, check out a sample notebook that shows the same features, but has a more interactive output.
String Interpolation
This preview adds String Interpolation, one of the most highly-requested language features and the very first feature that we had an initial design for in the F# Language Design repository. The design has undergone a lot of discussion over the years, but finally a breakthrough on how to best handle it was made by Yatao Li, who also supplied an initial implementation.
F# interpolated strings are fairly similar to C# or JavaScript interpolated strings, in that they let you write code in "holes" inside of a string literal. Here’s a basic example:
However, F# interpolated strings also allow for typed interpolations, just like the sprintf
function, to enforce that an expression inside of an interpolated context conforms to a particular type. It uses the same format specifiers.
Support for nameof is now complete
In the June update, we mentioned that we were finishing up several design changes for nameof
. These are now complete!
To recap, nameof
resolves the symbol it’s being used for and produces a name that represents what it’s called in F# source. This is useful in various scenarios, such as logging, and protects your logging against changes in source code.
The last line will throw an exception and "month" will be shown in the error message.
You can take a name of nearly everything in F#:
Three final additions are changes to how operators work: the addition of the nameof<'type-parameter>
form for generic type parameters, and the ability to use nameof
as a pattern in a pattern match expression.
The nameof<'type-parameter>
form aligns with how typeof
and typedefof
work in F# today.
Open Type declarations
This preview also adds Open Type Declarations. It’s like Open Static Classes in C#, except with some different syntax and some slightly different behavior to fit F# semantics.
With Open Type Declarations, you can open
any type to expose static contents inside of it. Additionally, you can open
F#-defined unions and records to expose their contents. This can be useful if you have a union defined in a module and want to access its cases, but don’t want to open the entire module.
Overloads of custom keywords in computation expressions
Computation expressions are a powerful feature for library and framework authors. They allow you to greatly improve the expressiveness of your components by letting you define well-known members and form a DSL for the domain you’re working in.
We’ve enhanced computation expressions to allow for Applicative forms already. This time, Diego Esmerio and Ryan Riley contributed a design and implementation to allow for overloading custom keywords in computation expressions. This new feature allows code like the following to be written:
Prior to this change, you could write the InputBuilder
type as it is, but you couldn’t use it the way it’s used in the previous example. Since overloads, optional parameters, and now System.ParamArray
types are allowed, everything just works as you’d expect it to.
Thanks, Diego and Ryan!
Interfaces can be implemented at different generic instantiations
The final feature enabled in this preview is an enhancement to interfaces in F#. You can now implement the same interface at different generic instantiations. Lukas Rieger contributed an initial design and implementation of this feature.
Thanks, Lukas!
Finishing F# 5
Now that we’re feature complete for F# 5, minus a tweak here or there, we’re going to shift our focus:
- Address bug fixes and high-priority feedback items for F# 5
- Improve our engineering system in the F# development repository, particularly to improve our testing infrastructure so that it’s easier for open source contributors to work there
After F# 5 ships alongside .NET 5, we’ll also start our planning for the next wave of F# investments. We’d love for you to join us when we get there.
Cheers, and happy F# coding!
This is so great. F# 5.0 has made this language almost perfect.
Really excited for NET 5.0.
Thank you all.
Thanks you! Glad to hear that the F# 5 feature set is aligning well with what you’re after. Looking forward to release this in the fall!
String Interpolation will be awesome (thanks to all involved, I was following also the recent discussions on twitter), but what about anonymous DUs? I saw little hope in the github thread (checked last week) due to some difficulties, but that will really complete my list of F# gaps which I really noticed in the practice!
Hey Deyan,
Anonymous Unions aren’t planned for F# 5. They may be considered for the next F# language version though, since they are certainly a useful feature. They would be a challenging feature to tackle, though.