{"id":29554,"date":"2020-08-27T17:14:17","date_gmt":"2020-08-28T00:14:17","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=29554"},"modified":"2020-08-31T16:34:17","modified_gmt":"2020-08-31T23:34:17","slug":"f-5-update-for-august","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/f-5-update-for-august\/","title":{"rendered":"F# 5 update for August"},"content":{"rendered":"<p>We\u2019re excited to announce more updates to F# 5 which will go alongside <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-net-5-0-preview-8\/\">.NET 5 preview 8<\/a>! We&#8217;ve shipped various updates since the beginning of this year:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-f-5-preview-1\/\">F# 5 preview 1<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/f-5-update-for-net-5-preview-4\/\">F# 5 update for .NET 5 preview 5<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/f-5-and-f-tools-update-for-june\/\">F# 5 update for June<\/a><\/li>\n<\/ul>\n<p>Today, we&#8217;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.<\/p>\n<p>You can get the latest F# 5 in these ways<\/p>\n<ul>\n<li><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet-core\/5.0\">Install the latest .NET 5 preview SDK<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/interactive\/#jupyter-and-nteract\">Install .NET for Jupyter\/nteract<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/interactive\/#visual-studio-code\">Install .NET for VSCode Notebooks<\/a><\/li>\n<\/ul>\n<p>If you\u2019re using Visual Studio on Windows, you\u2019ll need both the .NET 5 preview SDK and <a href=\"https:\/\/visualstudio.microsoft.com\/vs\/preview\/\">Visual Studio Preview installed<\/a>.<\/p>\n<h2>Using F# 5 preview<\/h2>\n<p>You can use F# 5 preview via the <a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet-core\/5.0\">.NET 5 preview SDK<\/a>, or through the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/net-interactive-is-here-net-notebooks-preview-2\/\">.NET and Jupyter Notebooks support<\/a>.<\/p>\n<p>If you\u2019re using the .NET 5 preview SDK, check out the <a href=\"https:\/\/github.com\/cartermp\/fs5preview\">sample repository<\/a> 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.<\/p>\n<p>If you\u2019d rather use F# 5 in your own project, you\u2019ll need to add a <code>LangVersion<\/code> property with <code>preview<\/code> as the value. It should look something like this:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/3a12e552cc64918d697c430c7b5cfcf7.js\"><\/script>\n<\/code><\/pre>\n<p>Alternatively, if you\u2019re using Jupyter Notebooks and want a more interactive experience, check out a <a href=\"https:\/\/gist.github.com\/cartermp\/6b91c3561c6a5efca4288dca37c15edc\">sample notebook<\/a> that shows the same features, but has a more interactive output.<\/p>\n<h2>String Interpolation<\/h2>\n<p>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 <a href=\"https:\/\/github.com\/fsharp\/fslang-design\">F# Language Design repository<\/a>. The design has undergone a lot of discussion over the years, but finally a breakthrough on how to best handle it was made by <a href=\"https:\/\/github.com\/yatli\">Yatao Li<\/a>, who also supplied an initial implementation.<\/p>\n<p>F# interpolated strings are fairly similar to C# or JavaScript interpolated strings, in that they let you write code in &quot;holes&quot; inside of a string literal. Here&#8217;s a basic example:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/4ed6b98cf35c650bef637b82efd26dc6.js\"><\/script><\/p>\n<p>However, F# interpolated strings also allow for typed interpolations, just like the <code>sprintf<\/code> function, to enforce that an expression inside of an interpolated context conforms to a particular type. It uses the same format specifiers.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/af61c08e3b2b6bfb810d7302b50a0328.js\"><\/script><\/p>\n<h2>Support for nameof is now complete<\/h2>\n<p>In the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/f-5-and-f-tools-update-for-june\/\">June update<\/a>, we mentioned that we were finishing up several design changes for <code>nameof<\/code>. These are now complete!<\/p>\n<p>To recap, <code>nameof<\/code> resolves the symbol it&#8217;s being used for and produces a name that represents what it&#8217;s called in F# source. This is useful in various scenarios, such as logging, and protects your logging against changes in source code.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/d3bb6ffadc7751b1616e42f3f96fbcb8.js\"><\/script><\/p>\n<p>The last line will throw an exception and &quot;month&quot; will be shown in the error message.<\/p>\n<p>You can take a name of nearly everything in F#:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/678dc8cde08565cbbb9726a0e65ffbdd.js\"><\/script><\/p>\n<p>Three final additions are changes to how operators work: the addition of the <code>nameof&lt;'type-parameter&gt;<\/code> form for generic type parameters, and the ability to use <code>nameof<\/code> as a pattern in a pattern match expression.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/4b633fb5ad214a2538d0dd93a7b794ad.js\"><\/script><\/p>\n<p>The <code>nameof&lt;'type-parameter&gt;<\/code> form aligns with how <code>typeof<\/code> and <code>typedefof<\/code> work in F# today.<\/p>\n<h2>Open Type declarations<\/h2>\n<p>This preview also adds Open Type Declarations. It&#8217;s like Open Static Classes in C#, except with some different syntax and some slightly different behavior to fit F# semantics.<\/p>\n<p>With Open Type Declarations, you can <code>open<\/code> any type to expose static contents inside of it. Additionally, you can <code>open<\/code> 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&#8217;t want to open the entire module.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/b2a30361927427314ab781c1bb30be98.js\"><\/script><\/p>\n<h2>Overloads of custom keywords in computation expressions<\/h2>\n<p>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&#8217;re working in.<\/p>\n<p>We&#8217;ve enhanced computation expressions to allow for <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-f-5-preview-1\/#applicative-computation-expressions\">Applicative forms<\/a> already. This time, <a href=\"https:\/\/github.com\/Nhowka\">Diego Esmerio<\/a> and <a href=\"https:\/\/github.com\/panesofglass\">Ryan Riley<\/a> 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:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/802d640dd1188100a30da93137d4fc6b.js\"><\/script><\/p>\n<p>Prior to this change, you could write the <code>InputBuilder<\/code> type as it is, but you couldn&#8217;t use it the way it&#8217;s used in the previous example. Since overloads, optional parameters, and now <code>System.ParamArray<\/code> types are allowed, everything just works as you&#8217;d expect it to.<\/p>\n<p>Thanks, Diego and Ryan!<\/p>\n<h2>Interfaces can be implemented at different generic instantiations<\/h2>\n<p>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. <a href=\"https:\/\/github.com\/0x53A\">Lukas Rieger<\/a> contributed an initial design and implementation of this feature.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/d25aede7921a36e88ee46b9b11386b4a.js\"><\/script><\/p>\n<p>Thanks, Lukas!<\/p>\n<h2>Finishing F# 5<\/h2>\n<p>Now that we&#8217;re feature complete for F# 5, minus a tweak here or there, we&#8217;re going to shift our focus:<\/p>\n<ul>\n<li>Address bug fixes and high-priority feedback items for F# 5<\/li>\n<li>Improve our engineering system in the <a href=\"https:\/\/github.com\/dotnet\/fsharp\">F# development repository<\/a>, particularly to improve our testing infrastructure so that it&#8217;s easier for open source contributors to work there<\/li>\n<\/ul>\n<p>After F# 5 ships alongside .NET 5, we&#8217;ll also start our planning for the next wave of F# investments. We&#8217;d love for you to join us when we get there.<\/p>\n<p>Cheers, and happy F# coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We\u2019re excited to announce more updates to F# 5 which will go alongside .NET 5 preview 8! We&#8217;ve shipped various updates since the beginning of this year: F# 5 preview 1 F# 5 update for .NET 5 preview 5 F# 5 update for June Today, we&#8217;re pleased to announce the completion of the F# 5 [&hellip;]<\/p>\n","protected":false},"author":678,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[],"class_list":["post-29554","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet"],"acf":[],"blog_post_summary":"<p>We\u2019re excited to announce more updates to F# 5 which will go alongside .NET 5 preview 8! We&#8217;ve shipped various updates since the beginning of this year: F# 5 preview 1 F# 5 update for .NET 5 preview 5 F# 5 update for June Today, we&#8217;re pleased to announce the completion of the F# 5 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/29554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/678"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=29554"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/29554\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=29554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=29554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=29554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}