{"id":28776,"date":"2020-06-26T10:20:06","date_gmt":"2020-06-26T17:20:06","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=28776"},"modified":"2020-06-26T10:20:06","modified_gmt":"2020-06-26T17:20:06","slug":"f-5-and-f-tools-update-for-june","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/f-5-and-f-tools-update-for-june\/","title":{"rendered":"F# 5 and F# tools update for June"},"content":{"rendered":"<p>We\u2019re excited to announce more updates to F# 5 today! We shipped an initial set of features with <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-f-5-preview-1\/\">F# 5 preview 1<\/a>, and they have all been stabilizing since that release including a <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/f-5-update-for-net-5-preview-4\/\">updates from last month<\/a>. Today, we\u2019re happy to announce some new language features, a sneak peek at using F# in VSCode notebooks, and some F# tooling updates that will align with Visual Studio 2019 Update 16.7.<\/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 a <a href=\"https:\/\/github.com\/cartermp\/fs5preview\">sample repository<\/a> showing 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><\/p>\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>Improvements to nuget references for F# scripts<\/h2>\n<p>Support for <code>#r \"nuget:...\"<\/code> has now been enhanced to support packages that pull in native dependencies. Prior to this update, some packages weren&#8217;t 100% usable if they needed to call into certain kinds of native code. This is now resolved. The following is an example of the <a href=\"https:\/\/www.nuget.org\/packages\/Flips\/\">Flips<\/a> library, which used to fail on the second-to-last line of code where it serialized a model. Now it works!<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/2adeac8ac012822b270509bc057490e6.js\"><\/script><\/p>\n<p>Additionally, we now support referencing packages where the order of <code>.dll<\/code> references being passed to a compiler matters, such as <a href=\"https:\/\/www.nuget.org\/packages\/FParsec\/\">FParsec<\/a>. The following script now works:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/9edcd5855a1eb453a4156e378d39f6a3.js\"><\/script><\/p>\n<p>This is also a significant improvement over the &#8220;old&#8221; way to use a package like this, where you needed to manually ensure the ordering of the <code>.dlls<\/code> being passed to the compiler to be able to use it in scripts.<\/p>\n<h2>Better interop with nullable value types<\/h2>\n<p><a href=\"https:\/\/docs.microsoft.com\/dotnet\/api\/system.nullable-1\">Nullable (value) types<\/a> (called Nullable Types historically) have long been supported by F#, but interacting with them has traditionally been somewhat of a pain since you&#8217;d have to construct a <code>Nullable<\/code> or <code>Nullable&lt;SomeType&gt;<\/code> wrapper every time you wanted to pass a value. Now the compiler will implicitly convert a value type into a <code>Nullable&lt;ThatValueType&gt;<\/code> if the target type matches. The following code is now possible:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/a0603f0e6da3693b2f243eabfbd977c7.js\"><\/script><\/p>\n<h2>Improved stack traces in F# async and other computation expressions<\/h2>\n<p>Thanks to a contribution by <a href=\"https:\/\/github.com\/NinoFloris\">Nino Floris<\/a>, stack traces coming from caught exceptions in computation expressions (such as F# async) now retain more information. Consider the following code that uses the Ply library:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/3c21f2a05876e4dc16778fa18a8c8a11.js\"><\/script><\/p>\n<p>Prior to this change, the <code>origin<\/code> function would not appear in stack traces without a workaround in the Ply library (and any other library where this is a scenario). Now it shows the full trace:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/4147b1ceefd84c67c55cc17f6a199784.js\"><\/script><\/p>\n<h2>What&#8217;s coming next<\/h2>\n<p>There are some more immediate updates we&#8217;re making that we hope to release in the next set of .NET 5 previews, now that we&#8217;ve resolved some longstanding design issues. There isn&#8217;t a way to use these changes in .NET 5 yet, though some may appear in Jupyter\/VSCode notebooks before the next .NET 5 release where they can be used anywhere.<\/p>\n<h3>F# quotations improvements<\/h3>\n<p>We&#8217;re finishing up a fundamental improvement to <a href=\"https:\/\/docs.microsoft.com\/dotnet\/fsharp\/language-reference\/code-quotations\">F# Code Quotations<\/a>, a metaprogramming feature that lets you generate and manipulate an abstract syntax tree that represents the F# code.<\/p>\n<p>Although powerful, F# Code Quotations have had a severe deficiency up until this point: they didn&#8217;t carry &#8220;trait calls&#8221; to sufficiently represent the actual semantics of the code being &#8220;quoted&#8221; if it relied on type constraints. A common way this could manifest itself was &#8220;allowing&#8221; code with arithmetic that would merely throw an exception at runtime.<\/p>\n<p>These enhancements are particularly relevant to translating F# code to run on other runtimes like <a href=\"https:\/\/pytorch.org\/\" rel=\"noopener noreferrer\" target=\"_blank\">PyTorch <\/a>or <a href=\"https:\/\/onnx.ai\/\" rel=\"noopener noreferrer\" target=\"_blank\">ONNX<\/a>, a key scenario we&#8217;re exploring as a means to attract developers in more &#8220;analytical&#8221; domains to F# and .NET. We also anticipate numerous smaller issues that F# developers using F# Code Quotations today had to work around to be resolved, with the code they expect to &#8220;just work&#8221; actually live up to that phrase.<\/p>\n<p>A trivial example of code that now just works is as follows:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/86a805c4858a908a2c492ea920fd3555.js\"><\/script><\/p>\n<p>This used to throw an exception. It now emits <code>-1<\/code> as you would expect it to.<\/p>\n<p>We&#8217;re also collaborating with the <a href=\"https:\/\/fable.io\/\" rel=\"noopener noreferrer\" target=\"_blank\">Fable<\/a> maintainers to ensure the underlying mechanism used to preserve constraints surfaces in the F# Compiler Service so that tools like Fable, WebSharper, etc. can accurately represent this sort of code without their own workarounds.<\/p>\n<p>To read more about this feature (warning: there is a <em>lot<\/em> to read about), you can check out the <a href=\"https:\/\/github.com\/fsharp\/fslang-design\/blob\/master\/preview\/FS-1071-witness-passing-quotations.md\" rel=\"noopener noreferrer\" target=\"_blank\">RFC that goes over the design in detail<\/a>.<\/p>\n<h3>Finishing up nameof<\/h3>\n<p>We&#8217;re finishing up our design changes for the <code>nameof<\/code> function and arrived at the following improvements:<\/p>\n<ul>\n<li>Change <code>nameof<\/code> on an operator to generate the symbol in source rather than the compiled name of the operator<\/li>\n<li>Allow <code>nameof<\/code> in <code>match<\/code> expressions<\/li>\n<li>Allowing taking the name of generic type parameters<\/li>\n<\/ul>\n<p>The last point was tricky from a design standpoint, and results in <code>nameof<\/code> actually having two forms:<\/p>\n<ul>\n<li><code>nameof expr<\/code><\/li>\n<li><code>nameof&lt;'type-parameter&gt;<\/code> \/ <code>nameof&lt;^type-parameter&gt;<\/code><\/li>\n<\/ul>\n<p>This second form for generic type parameters aligns <code>nameof<\/code> with the <code>typeof<\/code> and <code>typedefof<\/code> intrinsic functions that require a similar form. Here&#8217;s what the changes look like in source code:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/4b633fb5ad214a2538d0dd93a7b794ad.js\"><\/script><\/p>\n<h3>Open type declarations<\/h3>\n<p>We&#8217;re renaming the feature &#8220;open static classes&#8221; to &#8220;open type declarations&#8221;. This is because we&#8217;re making the following major changes:<\/p>\n<ul>\n<li>Syntax is now <code>open type SomeType<\/code> (old syntax was <code>open SomeType<\/code>)<\/li>\n<li>You can now open <em>any<\/em> type, not just a static class like before, and expose static members and constants contained within it<\/li>\n<\/ul>\n<p>Code will now look like this:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/6901e59b8ab8a46ffa055b5ec02698d3.js\"><\/script><\/p>\n<h3>Allow implementing the same interface at different generic instantiations<\/h3>\n<p>As another example of F# open source community excellence, <a href=\"https:\/\/github.com\/0x53A\">Lukas Rieger<\/a> contributed an initial design and implementation of this feature. In a future F# 5 preview, code like this will be able to compile:<\/p>\n<p><script src=\"https:\/\/gist.github.com\/cartermp\/d25aede7921a36e88ee46b9b11386b4a.js\"><\/script><\/p>\n<h2>F# and VSCode notebooks<\/h2>\n<p>We&#8217;re really excited to share the first preview of F# support for VSCode notebooks. It uses the same kernel that powers F# support in Jupyter, except it plugs into a different system that enables a richer overall experience.<\/p>\n<p>Here&#8217;s what it looks like when executing one of the code samples in this blog post:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.22.08.png\" alt=\"Image Screen Shot 2020 06 26 at 08 22 08\" width=\"1240\" height=\"910\" class=\"alignnone size-full wp-image-28788\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.22.08.png 1240w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.22.08-300x220.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.22.08-1024x751.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.22.08-768x564.png 768w\" sizes=\"(max-width: 1240px) 100vw, 1240px\" \/><\/p>\n<p>It also supports inline charts (in this case via the XPlot.plotly package):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/fsharp-charting-vscode-notebooks.png\" alt=\"Image fsharp charting vscode notebooks\" width=\"997\" height=\"690\" class=\"alignnone size-full wp-image-28783\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/fsharp-charting-vscode-notebooks.png 997w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/fsharp-charting-vscode-notebooks-300x208.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/fsharp-charting-vscode-notebooks-768x532.png 768w\" sizes=\"(max-width: 997px) 100vw, 997px\" \/><\/p>\n<p>And you can import\/export Jupyter notebooks:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/net-interactive-menu.png\" alt=\"Image net interactive menu\" width=\"570\" height=\"175\" class=\"alignnone size-full wp-image-28784\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/net-interactive-menu.png 570w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/net-interactive-menu-300x92.png 300w\" sizes=\"(max-width: 570px) 100vw, 570px\" \/><\/p>\n<p>It&#8217;s an early preview, but it supports some great features already<\/p>\n<ul>\n<li>Preliminary language service support<\/li>\n<li>Inline charting and formatting of data<\/li>\n<li>Compact data format (<code>.dib<\/code>) that makes code review easy<\/li>\n<li>Ability to import Jupyter notebooks (<code>.ipynb<\/code>) and convert to a <code>.dib<\/code><\/li>\n<li>Ability to export a <code>.dib<\/code> notebook as a Jupyter notebook (<code>.ipynb<\/code>)<\/li>\n<\/ul>\n<p>Some features on the more immediate roadmap include:<\/p>\n<ul>\n<li>Tooltips<\/li>\n<li>Better IntelliSense<\/li>\n<li>Sharing F#-defined values with JavaScript cells<\/li>\n<li>Sharing F#-defined values with C# cells<\/li>\n<\/ul>\n<p>We&#8217;d love to have you try it out and give us feedback on what you feel needs to be there. To do so, follow the <a href=\"https:\/\/github.com\/dotnet\/interactive\/blob\/master\/src\/dotnet-interactive-vscode\/README.md\">installation instructions<\/a>.<\/p>\n<p>A great way to get started is to download the F# 5 Jupyter notebook and convert it like so:<\/p>\n<ol>\n<li>Download the file into a folder or existing workspace<\/li>\n<li>Open the VSCode command palette<\/li>\n<li>Type in <code>&gt;.NET Interactive<\/code><\/li>\n<li>Select the option to import a Jupyter notebook<\/li>\n<li>Name the new file <code>FILENAME.dib<\/code><\/li>\n<\/ol>\n<p>If something seems off, doesn&#8217;t work right, or a feature is missing, don&#8217;t be shy and <a href=\"https:\/\/github.com\/dotnet\/interactive\/\" rel=\"noopener noreferrer\" target=\"_blank\">file an issue on GitHub<\/a>! The team wants your feedback.<\/p>\n<h2>.NET Framework projects default to SDK-style project files<\/h2>\n<p>Starting with the Visual Studio 16.7 update, we&#8217;ve deprecated the older &#8220;long-form&#8221; F# projects. They will still load in Visual Studio today, but any new projects you create will only be .NET SDK-style moving forward. The project files now look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/net-fsharp-project.png\" alt=\"Image net fsharp project\" width=\"692\" height=\"316\" class=\"alignnone size-full wp-image-28785\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/net-fsharp-project.png 692w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/net-fsharp-project-300x137.png 300w\" sizes=\"(max-width: 692px) 100vw, 692px\" \/><\/p>\n<h3>IntelliSense improvements<\/h3>\n<p>Keyword descriptions now show in completion lists:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.29.05.png\" alt=\"Image Screen Shot 2020 06 26 at 08 29 05\" width=\"1470\" height=\"256\" class=\"alignnone size-full wp-image-28790\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.29.05.png 1470w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.29.05-300x52.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.29.05-1024x178.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.29.05-768x134.png 768w\" sizes=\"(max-width: 1470px) 100vw, 1470px\" \/><\/p>\n<p>Extended completion (showing completion for unimported types, an optional feature) now uses the same built-in UI that C# does. The completion window will dynamically resize depending on the size of the namespace to open:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.28.54.png\" alt=\"Image Screen Shot 2020 06 26 at 08 28 54\" width=\"1394\" height=\"562\" class=\"alignnone size-full wp-image-28791\" srcset=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.28.54.png 1394w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.28.54-300x121.png 300w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.28.54-1024x413.png 1024w, https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2020\/06\/Screen-Shot-2020-06-26-at-08.28.54-768x310.png 768w\" sizes=\"(max-width: 1394px) 100vw, 1394px\" \/><\/p>\n<p>When typing at the top of a file (such as in an F# script), using a code fixer via IntelliSense to add a necessary <code>open<\/code> declaration will now work correctly.<\/p>\n<p>Various improvements to error recovery and data shown in tooltips have been contributed by <a href=\"https:\/\/github.com\/auduchinok\">Eugene Auduchinok<\/a> and <a href=\"https:\/\/github.com\/mcon\">Matt Constable<\/a>.<\/p>\n<h3>More performance improvements for Visual Studio tooling<\/h3>\n<p>The performance work for larger codebases is always ongoing, focused primarily on elminating some unnecessary memory usage over time. <a href=\"https:\/\/github.com\/forki\/\">Steffen Forkmann<\/a> also helped in this effort with some improvements.<\/p>\n<p>Additionally, <a href=\"https:\/\/github.com\/saul\">Saul Rennison<\/a> contributed an improvement to CPU time spend building F# projects at design-time in Visual Studio, a process that happens ambiently and many times over a session. The bottleneck identified has had its CPU time reduced by ~90%. If you have a lot of F# projects in a solution, you may notice that various things feel &#8220;quicker&#8221; than before.<\/p>\n<p>Thank you to everyone who has contributed! F# is continually improving because of your work.<\/p>\n<h2>The continuing F# 5 journey<\/h2>\n<p>We&#8217;re still not done with F# 5, and aside from what I mentioned earlier about what&#8217;s next, we&#8217;ll be focused on these three things:<\/p>\n<ol>\n<li>Continuing inclusion of language features when their design and implementations are stable<\/li>\n<li>Continuing to improve the tooling performance for larger F# codebases<\/li>\n<li>Making F# in Jupyter and Visual Studio Code Notebooks the best language for data science and analytical work<\/li>\n<\/ol>\n<p>Later this year we will &#8220;close down&#8221; on F# 5, marking a period of time where we focus on stabilization and planning for the next F# language version. We don&#8217;t have a date in mind for that year, but we&#8217;re thinking it will be near the end of the Summer. Until that point, If you&#8217;d like to follow along on a much more detailed level, you can check out the <a href=\"https:\/\/github.com\/dotnet\/fsharp\">F# development repository<\/a>. We&#8217;re tracking the work we&#8217;re focused on with a GitHub issue roughly each month, and we encourage you all to provide input to the list of things and let us know what you think.<\/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 today! We shipped an initial set of features with F# 5 preview 1, and they have all been stabilizing since that release including a updates from last month. Today, we\u2019re happy to announce some new language features, a sneak peek at using F# in VSCode notebooks, [&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-28776","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 today! We shipped an initial set of features with F# 5 preview 1, and they have all been stabilizing since that release including a updates from last month. Today, we\u2019re happy to announce some new language features, a sneak peek at using F# in VSCode notebooks, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/28776","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=28776"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/28776\/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=28776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=28776"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=28776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}