<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: André Slupik</title>
    <description>The latest articles on DEV Community by André Slupik (@asik).</description>
    <link>https://dev.to/asik</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F522735%2F642b3696-1ba0-4c45-bf3b-3de7a0446fe5.jpeg</url>
      <title>DEV Community: André Slupik</title>
      <link>https://dev.to/asik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/asik"/>
    <language>en</language>
    <item>
      <title>ReScript is not there yet</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Wed, 02 Oct 2024 05:58:16 +0000</pubDate>
      <link>https://dev.to/asik/rescript-is-not-there-yet-1ood</link>
      <guid>https://dev.to/asik/rescript-is-not-there-yet-1ood</guid>
      <description>&lt;p&gt;As a fan of ML-inspired languages, I always found &lt;a href="https://rescript-lang.org/" rel="noopener noreferrer"&gt;ReScript&lt;/a&gt; intriguing. With async-await now recently added to the language, is it time for ReScript to shine?&lt;/p&gt;

&lt;p&gt;It sure looks enticing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;... you can pick up ReScript and access the vast JavaScript ecosystem and tooling as if you've known ReScript for a long time&lt;a href="https://rescript-lang.org/docs/manual/latest/introduction" rel="noopener noreferrer"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doesn't force you to search for pre-made binding libraries made by others. ReScript doesn't need the equivalent of TypeScript's &lt;code&gt;DefinitelyTyped&lt;/code&gt;.&lt;a href="https://rescript-lang.org/docs/manual/latest/converting-from-js" rel="noopener noreferrer"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the goal of this project?&lt;/strong&gt;&lt;br&gt;
​We aim to provide the best typed language experience for the JavaScript platform.&lt;a href="https://rescript-lang.org/docs/manual/latest/faq" rel="noopener noreferrer"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wow, so they provide the best typed language experience for the JavaScript platform, all without the need for pre-made bindings! Let's give it a go!&lt;/p&gt;

&lt;p&gt;We quickly hit a wall as we attempt to do the most basic thing possible:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foafkxzqa59dusxr6mx5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foafkxzqa59dusxr6mx5m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hmm.. why is &lt;code&gt;getElementById&lt;/code&gt; not on &lt;code&gt;document&lt;/code&gt;? What's the type of &lt;code&gt;document&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rescript-lang.org/docs/manual/latest/api/dom#type-_document" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vk4zndvoitw4d07oy4i.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This picture is all the ReScript documentation has to say about it. No definition of &lt;code&gt;Dom.document&lt;/code&gt;. F12 leads us down a chain of empty type definitions, so &lt;code&gt;Dom.document&lt;/code&gt; does look like a simple alias for the JS &lt;code&gt;document&lt;/code&gt;, nothing more. &lt;/p&gt;

&lt;p&gt;Wait, so I do need pre-made bindings? What happened to "Doesn't force you to search for pre-made binding libraries made by others"?&lt;/p&gt;

&lt;p&gt;Enter the &lt;a href="https://github.com/TheSpyder/rescript-webapi" rel="noopener noreferrer"&gt;rescript-webapi&lt;/a&gt; npm package, &lt;em&gt;Bindings to the DOM and other browser-specific web APIs.&lt;/em&gt;. I follow the instructions and compiler errors, including one telling me I might have a configuration issue in "bsconfig.json", even though this file is now called "rescript.json". I get that working eventually.&lt;/p&gt;

&lt;p&gt;Here's how it looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rescript"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nn"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// For the uninitiated, -&amp;gt; is the pipe operator.&lt;/span&gt;
&lt;span class="c1"&gt;// a-&amp;gt;foo means foo(a)&lt;/span&gt;
&lt;span class="c1"&gt;// a-&amp;gt;foo(b) means foo(a, b)&lt;/span&gt;
&lt;span class="c1"&gt;// The above code is therefore equivalent to&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;, &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll notice that &lt;code&gt;document.&lt;/code&gt; will bring up no code completion, as it's still basically untyped. I have to know what module and module function to call.&lt;/p&gt;

&lt;p&gt;So the IDE won't help me type the right thing, but will it give me good information about the function I'm calling? Not really:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feeaazeeji8u3ajyvoi8r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feeaazeeji8u3ajyvoi8r.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For reference, here's TypeScript out of the box:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffrlt3khmhvmq2ieu06an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffrlt3khmhvmq2ieu06an.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Informative error, link to examples, detailed type definition. Thank you. This saves me time, effort, teaches me right as I type - this is one of the main reasons I like static typing. I'm just not getting this with ReScript.&lt;/p&gt;

&lt;p&gt;If interacting with the DOM - &lt;em&gt;the reason why JavaScript was created&lt;/em&gt; - is not deemed important enough to warrant built-in bindings, I think I've seen enough.&lt;/p&gt;

&lt;p&gt;Is ReScript ready in 2024? No. Its official documentation makes lofty promises that seem outright misleading. I guess ReScript can be useful if you will write a lot of ReScript code that mostly interacts with other ReScript code. But one cannot simply ignore "the vast JavaScript ecosystem". Imagine F# without support for the BCL. Luckily, F# and its tooling were designed to consume C# types and documentation seamlessly. Surely there must be a way to leverage &lt;code&gt;DefinitelyTyped&lt;/code&gt; in ReScript. Until ReScript does this, I don't think it can seriously compete with TypeScript.&lt;/p&gt;

</description>
      <category>rescript</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Discriminated unions in 2024</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Wed, 18 Sep 2024 08:56:40 +0000</pubDate>
      <link>https://dev.to/asik/discriminated-unions-in-2024-3gpf</link>
      <guid>https://dev.to/asik/discriminated-unions-in-2024-3gpf</guid>
      <description>&lt;p&gt;Here are some slightly edited notes I took while researching a solution for discriminated unions in C#. I assume the reader is familiar with discriminated unions, wants to use them, has summarily searched Google and StackOverflow already, and is looking for more information beyond the basics.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about OneOf?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mcintyre321/OneOf" rel="noopener noreferrer"&gt;OneOf&lt;/a&gt; is implemented as a non-overlapping struct so&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ It can grow large in size.&lt;/li&gt;
&lt;li&gt;❌ It introduces value semantics complications: default instances, mutations, copying and passing by reference.&lt;/li&gt;
&lt;li&gt;❌ Plus, it's not serializable; an &lt;a href="https://github.com/dpraimeyuu/OneOf.Serialization" rel="noopener noreferrer"&gt;unrelated library&lt;/a&gt; does that, but forces me to take a dependency on &lt;code&gt;Newtonsoft.Json&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Can we do better?
&lt;/h3&gt;

&lt;p&gt;I experimented with a modernized version of what I was doing circa 2014: a generic base class with subclasses for each case, where Match is a virtual method, e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Case0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
            &lt;span class="nf"&gt;func0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;Case1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
            &lt;span class="nf"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this approach eliminates value type concerns, some issues remain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ It's annoying to have to alias these (it doesn't cross assembly boundaries)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;  &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;EntityState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyGame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartingState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MyGame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EndingState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;❌ Serializing this requires use of a &lt;code&gt;JsonConverterFactory&lt;/code&gt;, which means the user must remember to use the proper &lt;code&gt;JsonSerializerOption&lt;/code&gt; object referencing said factory.&lt;/li&gt;
&lt;li&gt;❌ More importantly, the &lt;code&gt;Match&lt;/code&gt; function takes N delegates, meaning every call to &lt;code&gt;Match&lt;/code&gt; causes N (typically 2-5) &lt;code&gt;Func&lt;/code&gt; allocations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Can we do better?
&lt;/h3&gt;

&lt;p&gt;Records offer a relatively clean syntax for what approximates a real union type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;EntityState&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;StaticState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vector2&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntityState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;MovingState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vector2&lt;/span&gt; &lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Vector2&lt;/span&gt; &lt;span class="n"&gt;Velocity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntityState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means we rely on switch expressions rather than a &lt;code&gt;Match&lt;/code&gt; function with lambdas for each case. Unfortunately, unlike lambdas, &lt;a href="https://github.com/dotnet/csharplang/issues/3037" rel="noopener noreferrer"&gt;switch expressions don't allow blocks of code&lt;/a&gt;. However, we can emulate them like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entityState&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;StaticState&lt;/span&gt; &lt;span class="n"&gt;staticState&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Do whatever here, you got a block of code&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;

    &lt;span class="n"&gt;MovingState&lt;/span&gt; &lt;span class="n"&gt;movingState&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="p"&gt;.,&lt;/span&gt;

    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you squint, the &lt;code&gt;Invoke(() =&amp;gt;&lt;/code&gt; noise practically disappears. This still incurs allocations, but it's only 1 per match rather than N.&lt;br&gt;
We also leverage the full power of pattern-matching here(deconstruction etc.) which isn't accessible in lambda parameters.&lt;br&gt;
The thing that bugs me the most is the non-exhaustiveness and the unnecessary yet mandatory default clause e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tried &lt;a href="https://github.com/WalkerCodeRanger/ExhaustiveMatching" rel="noopener noreferrer"&gt;ExhaustiveMatching&lt;/a&gt;, and found that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I still have to add a default clause to every switch&lt;/li&gt;
&lt;li&gt;Every time I add a default clause, I have to remember to use their special exception to trigger the analyzer&lt;/li&gt;
&lt;li&gt;When I add a case to the type I have to remember to add it to their special &lt;code&gt;Closed&lt;/code&gt; attribute type list

&lt;ul&gt;
&lt;li&gt;And no, this can't be automated with a source generator, as it will not run before the analyzer and there is no way to control that.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;That's still a lot of potential for error. As a result, I do not feel compelled to use this analyzer.&lt;/p&gt;

&lt;p&gt;We can make these record hierarchies serializable without forcing specific &lt;code&gt;JsonSerializerOptions&lt;/code&gt; everywhere, &lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism" rel="noopener noreferrer"&gt;by adding a &lt;code&gt;JsonDerivedTypeAttribute&lt;/code&gt; to the base type for each case&lt;/a&gt;.&lt;br&gt;
This &lt;strong&gt;can&lt;/strong&gt; be automated with a source generator, which requires marking the records partial so the source generator can add a identically named partial record with the appropriate attributes.&lt;/p&gt;

&lt;p&gt;To ensure the developer would not forget to add the partial keyword, I had the generator generate warnings for non-partial abstract records.&lt;/p&gt;

&lt;p&gt;In summary, this final solution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✔️ leverages modern language features: records, switch expressions, pattern matching&lt;/li&gt;
&lt;li&gt;✔️ does not require usage of a specific library except for an optional source generator&lt;/li&gt;
&lt;li&gt;✔️ does not incur excessive allocations (use of the &lt;code&gt;Invoke&lt;/code&gt; trick above is optional)&lt;/li&gt;
&lt;li&gt;✔️ does not suffer from value semantics complications&lt;/li&gt;
&lt;li&gt;✔️ is serializable with minimal noise and no added maintenance burden (just a &lt;code&gt;partial&lt;/code&gt; keyword)&lt;/li&gt;
&lt;li&gt;✔️ approximates the &lt;a href="https://github.com/dotnet/csharplang/blob/main/proposals/TypeUnions.md#implementation" rel="noopener noreferrer"&gt;proposed syntax for "Union Classes"&lt;/a&gt; in C# &lt;/li&gt;
&lt;li&gt;❌ fails to achieve exhaustiveness&lt;/li&gt;
&lt;li&gt;❌ is somewhat slow (switch on types results in several casts and branches)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This may be the best compromise until C# adds support for some kind of closed type hierarchies (e.g. &lt;a href="https://github.com/dotnet/csharplang/blob/main/proposals/TypeUnions.md" rel="noopener noreferrer"&gt;Type Union Proposal&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Async gotcha: returning Task.FromResult or Task.CompletedTask</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Fri, 01 Apr 2022 19:23:53 +0000</pubDate>
      <link>https://dev.to/asik/dont-return-taskfromresult-or-taskcompletedtask-4gcp</link>
      <guid>https://dev.to/asik/dont-return-taskfromresult-or-taskcompletedtask-4gcp</guid>
      <description>&lt;p&gt;So you're implementing this async handler or interface method that doesn't have anything to await, and you write something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nf"&gt;DoSomethingSynchronous&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But now the C# compiler emits a stern warning: "CS1998: you're using &lt;code&gt;async&lt;/code&gt;, so you should be awaiting stuff! find something to await!"* Well, you have nothing to await, but you must still return Task. You remove &lt;code&gt;async&lt;/code&gt; and return &lt;code&gt;Task.FromResult(true)&lt;/code&gt; instead, as &lt;a href="https://stackoverflow.com/a/29923484" rel="noopener noreferrer"&gt;top-rated&lt;/a&gt; answers by &lt;a href="https://stackoverflow.com/a/16526019" rel="noopener noreferrer"&gt;high-reputation members&lt;/a&gt; on Stackoverflow recommend. Job done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;DoSomethingSynchronous&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or is it?&lt;/p&gt;

&lt;p&gt;As long as &lt;code&gt;HandleAsync&lt;/code&gt; is always called and awaited immediately, all is fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// This is fine.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this doesn't always do what you'd expect. Sometimes a try-catch fails to catch an exception.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task0&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;task0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// this handler does nothing and the exception escapes! What gives??&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;HandleAsync&lt;/code&gt; is actually synchronous, any exception propagates as soon as it's called, not when it's awaited. &lt;strong&gt;This is surprising to most C# programmers.&lt;/strong&gt; A &lt;em&gt;synchronous method that returns a Task&lt;/em&gt; is not what you expect, especially when it's called SomethingAsync. Surprising, unexpected behavior leads to bugs. Bugs lead to unhappy customers and developers alike.&lt;/p&gt;

&lt;p&gt;So what should we do instead?&lt;/p&gt;

&lt;p&gt;One option would be to disable warning CS1998, but it may point out cases where a method just shouldn't return a Task in the first place. Probably the best thing would be to mark the function as async and await &lt;code&gt;Task.FromResult&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;HandleAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;DoSomethingNotAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if it's a plain &lt;code&gt;Task&lt;/code&gt;, awaiting &lt;code&gt;Task.CompletedTask&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;HandlerAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;DoSomethingNotAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CompletedTask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is this slower? Not much - awaiting a completed task does almost nothing, and the runtime might be able to recognize this common pattern and elide all the overhead - but choosing the async-looking-but-actually-synchronous behavior for hypothetical performance reasons firmly falls in the category "&lt;a href="https://wiki.c2.com/?PrematureOptimization" rel="noopener noreferrer"&gt;evil premature optimization&lt;/a&gt;", in my opinion.&lt;/p&gt;

&lt;p&gt;*Actually, it says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;warning CS1998: This async method lacks ‘await’ operators and will run synchronously. Consider using the ‘await’ operator to await non-blocking API calls, or ‘await Task.Run(…)’ to do CPU-bound work on a background thread.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Seriously, stop using List&lt;T&gt; in APIs</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Tue, 29 Mar 2022 00:55:59 +0000</pubDate>
      <link>https://dev.to/asik/seriously-stop-using-list-in-apis-26o0</link>
      <guid>https://dev.to/asik/seriously-stop-using-list-in-apis-26o0</guid>
      <description>&lt;p&gt;&lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; is to collections what &lt;code&gt;StringBuilder&lt;/code&gt; is to strings. It's a mechanism for imperatively building a collection. &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; is designed for things like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IReadOnlyCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;inputElem&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inputElements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(...)&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputElem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; does not appear in the function signature, our API: it is an implementation detail, a mechanism. What the API says is give me any sort of &lt;a href="https://dev.to/asik/why-you-probably-shouldnt-use-ienumerableseq-3g6g"&gt;finite&lt;/a&gt; collection, and I'll give you back another finite, indexed collection. The caller does not need to read the implementation to understand this.&lt;/p&gt;

&lt;p&gt;Let's see what happens if we replace the input element with &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is now a confusing and restrictive function signature. It returns a collection, but it can also add, remove or change elements in the input collection. Does it? The caller doesn't know. He'd have to read the code, meaning that our API is no longer a clear abstraction. Furthermore the caller cannot pass in an &lt;code&gt;Array&lt;/code&gt;, an &lt;code&gt;ImmutableArray&lt;/code&gt; or any other collection, when these would in fact work perfectly fine for our purposes.&lt;/p&gt;

&lt;p&gt;Don't take &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; as an input argument unless you mean to modify that input argument. In that case, your function should probably then return &lt;code&gt;void&lt;/code&gt; (or &lt;code&gt;Task&lt;/code&gt;, if it's async).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AddElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// this does make sense&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's look at the other case, the return type. What would this mean?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IReadOnlyCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not restrictive, but it's equally confusing. The function returns a collection which may then be modified by the caller. Why? Does the function store a reference to it somewhere so it can observe the changes later? Or worse, does it modify it while it's being used? Again, this is just strange API design that prompts me to read the implementation when I shouldn't have to.&lt;/p&gt;

&lt;p&gt;I have a hard time coming up with a good reason to return &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;: if you have an internal mutable collection, surely it's a bad idea to share it with the outside world where it may be modified unexpectedly. Mutable state is best kept local.&lt;/p&gt;

&lt;p&gt;Note that strictly speaking, returning &lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt; does not guarantee immutability either, but it does send a strong message in that direction. Strictly speaking, the correct return type would be &lt;code&gt;ImmutableArray&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;ImmutableList&amp;lt;T&amp;gt;&lt;/code&gt;. I'm still on the fence; libraries seem to gravitate towards the &lt;code&gt;IReadOnly&lt;/code&gt; interfaces more than &lt;code&gt;System.Collections.Immutable&lt;/code&gt;, for whatever reason.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Why you probably shouldn't use IEnumerable&lt;T&gt;/seq&lt;T&gt;</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Thu, 03 Mar 2022 23:01:13 +0000</pubDate>
      <link>https://dev.to/asik/why-you-probably-shouldnt-use-ienumerableseq-3g6g</link>
      <guid>https://dev.to/asik/why-you-probably-shouldnt-use-ienumerableseq-3g6g</guid>
      <description>&lt;p&gt;What's wrong with this code?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// C#:&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// F#&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mutable&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you said, "calling this function may hang forever", you'd be right. Here's a valid value for &lt;code&gt;IEnumerable&amp;lt;int&amp;gt;&lt;/code&gt; (&lt;code&gt;seq&amp;lt;int&amp;gt;&lt;/code&gt; in F#) that we could pass into our &lt;code&gt;Sum&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// C#&lt;/span&gt;
&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GenerateValues&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// F#&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;generateValues&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
    &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initInfinite&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;Sum(GenerateValues())&lt;/code&gt; hangs forever.&lt;/p&gt;

&lt;p&gt;What's wrong with this code?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// C#&lt;/span&gt;
&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IConfigValuesProvider&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConfigValue&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ConfigValues&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myConfigValueProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigValues&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// F#&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;IConfigValuesProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="nc"&gt;ConfigValues&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ConfigValues&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myConfigValueProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ConfigValues&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, nothing, probably, but you can't really be sure. Since &lt;code&gt;ConfigValues&lt;/code&gt; is an &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;, it could technically be infinite, causing &lt;code&gt;Count&lt;/code&gt;/&lt;code&gt;Seq.length&lt;/code&gt; to hang, although, granted, that's unlikely. What sounds more plausible is that &lt;code&gt;ConfigValues&lt;/code&gt; is implemented as the output of calls to &lt;code&gt;Where&lt;/code&gt; or &lt;code&gt;Select&lt;/code&gt;, and that iterating it is computationally expensive. Note that we're potentially causing it to be iterated twice here (calling &lt;code&gt;Count&lt;/code&gt; and then doing a &lt;code&gt;foreach&lt;/code&gt;), which would be bad if it was computationally expensive. Of course, the caller expects this to behave like an Array-like collection, but as a matter of fact, &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; makes no such promises. A potential solution here would be calling &lt;code&gt;ConfigValue.ToArray()&lt;/code&gt; and using the result of that, but that's going to create a pointless copy if &lt;code&gt;ConfigValues&lt;/code&gt; is actually just a collection. We can't know, so either we make unsafe assumptions, or we code defensively and waste resources.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;/&lt;code&gt;seq&amp;lt;T&amp;gt;&lt;/code&gt; does not represent a collection of items, so it should not be used to represent collections of items. &lt;/p&gt;

&lt;p&gt;So what should we use? Is there another interface that all collections implement and provide a guarantee that it's actually a collection? Yes, there is, and it's called &lt;code&gt;IReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt;, introduced in .NET 4.5, August 15th, 2012. If you want to be more specific and get true array-like behavior (with indexing support), &lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt; has got your back. I'm leaning towards &lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt; for everything that has an index (arrays, &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableArray&amp;lt;T&amp;gt;&lt;/code&gt;, etc.) and &lt;code&gt;IReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt; for everything else (&lt;code&gt;LinkedList&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Queue&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;Stack&amp;lt;T&amp;gt;&lt;/code&gt;, etc.) There might be cases where concrete immutable collections like &lt;code&gt;ImmutableArray&amp;lt;T&amp;gt;&lt;/code&gt; are better though, especially as a return type. Returning a concrete type seems to provide greater value. I haven't found great, clear guidance on e.g. &lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt; vs &lt;code&gt;ImmutableArray&amp;lt;T&amp;gt;&lt;/code&gt;; if you have an opinion on that, please share! &lt;/p&gt;

&lt;p&gt;Finally, if &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; does not represent collections, and we have a perfect replacement for it, what use does it have? &lt;/p&gt;

&lt;p&gt;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; is anything that supports enumeration: collections, infinite sequences, computations of successive values. It is the perfect type to define mappings over arbitrary, non-finite sequences of data. Think of LINQ operators &lt;code&gt;Where&lt;/code&gt;, &lt;code&gt;Select&lt;/code&gt;, which also return &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;: those make perfect sense and could not use a better type. Do &lt;em&gt;not&lt;/em&gt; think of scalar-returning functions like &lt;code&gt;Enumerable.Sum&lt;/code&gt; or &lt;code&gt;Enumerable.Count&lt;/code&gt; which IMO shouldn't exist, as they don't make sense (and won't work) over anything but finite collections. &lt;/p&gt;

&lt;p&gt;I suspect that the late addition of &lt;code&gt;IReadOnlyCollection&amp;lt;T&amp;gt;&lt;/code&gt; and friends to .NET is largely to blame for the widespread use of &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; as a read-only view of a collection. After all, &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; arrived in .NET 2, early 2006, and &lt;code&gt;System.Linq&lt;/code&gt; arrived in .NET 3.5, late 2007. F#'s &lt;code&gt;Seq&lt;/code&gt; module, probably designed around the same time, is full of the same issues as &lt;code&gt;System.Linq&lt;/code&gt;: &lt;code&gt;Seq.sum&lt;/code&gt;, &lt;code&gt;Seq.length&lt;/code&gt;, &lt;code&gt;Seq.append&lt;/code&gt;, &lt;code&gt;Seq.toList&lt;/code&gt;, &lt;code&gt;Seq.toArray&lt;/code&gt;, etc. are all very practical, but definitely not sound.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>fsharp</category>
    </item>
    <item>
      <title>F# features C# will never get</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Wed, 02 Mar 2022 04:30:07 +0000</pubDate>
      <link>https://dev.to/asik/f-features-c-will-never-get-51o9</link>
      <guid>https://dev.to/asik/f-features-c-will-never-get-51o9</guid>
      <description>&lt;p&gt;C# has made huge strides in enabling programming with values and data transformation, as opposed to mutable entities. While C# generally embraces mutability, its records are immutable. Their concise syntax eliminate any arguments for primitive obsession. Switch expressions and pattern matching allow more logic to be expressed as a chain of expressions rather than imperative logic. Like early spring flowers poking out of the snow, there's even some traction to break free from classes, with a classless Program.cs or ASP.NET Minimal APIs. The C# compiler team seems determined to eventually add primary constructors and discriminated unions. With C# destined to get full algebraic data type support, one is bound to ask: will F# remain relevant?&lt;/p&gt;

&lt;p&gt;While C# is undoubtedly more and more capable, its roots in the C family of languages (C, C++, Java, JavaScript) will always make the experience of writing code in it somewhat akward in my opinion. F# remains and will remain vastly more concise, flexible and, to be perfectly objective, fun.&lt;br&gt;
Here are some F# features C# will probably never have:&lt;/p&gt;
&lt;h3&gt;
  
  
  1) Curried functions
&lt;/h3&gt;

&lt;p&gt;Curried functions enable partial application, which &lt;a href="https://blog.ploeh.dk/2017/01/30/partial-application-is-dependency-injection/"&gt;enables dependency injection without objects&lt;/a&gt;. While C# takes some steps back from object orientation, it has to remain object-based. In contrast, F# offers the flexibility of programming with functions or objects: both are just as powerful. While it's possible to write a curried function in C#, the lack of language support and type inference for it makes it impractical. With no traction for it in the community as far as I'm aware, we'll probably never see this feature in C#.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Wait what?&lt;/span&gt;
&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CurriedFunction&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Global type inference
&lt;/h3&gt;

&lt;p&gt;F# features full Hindley-Milner type inference, which enables writing in a functional style without the inconvenience of spelling out painful type signatures. It also largely contributes to F# programs being much more concise than the C# equivalent. This is heavily dependent on the expression-based nature of F#. Expressions have types; statements do not. While C# could make small improvements on its type inference, there's very little chance it could ever infer argument types or even return types.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Automatic generalization
&lt;/h3&gt;

&lt;p&gt;As F# performs type inference, it tries to come up with generic function signatures as much as possible. As C# does not and cannot ever infer function signatures, it cannot do this either.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Immutability consistently, by default, everywhere
&lt;/h3&gt;

&lt;p&gt;F# defaults to immutability everywhere: in its &lt;code&gt;let&lt;/code&gt; bindings, its function arguments, constructor arguments, class fields, but also its native collection types: &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Seq&lt;/code&gt;, &lt;code&gt;Set&lt;/code&gt;, &lt;code&gt;Map&lt;/code&gt; are immutable; &lt;code&gt;Array&lt;/code&gt; is not (it's just the .NET Array), but the &lt;code&gt;Array&lt;/code&gt; module leans heavily towards copy-and-update operations. &lt;br&gt;
C# seems decidedly undecided, with immutable records but mutable tuples, and of course mutable everything pre-records. Immutable collections &lt;em&gt;exist&lt;/em&gt; (in &lt;code&gt;System.Collections.Immutable&lt;/code&gt;), but they lack language support (&lt;code&gt;ImmutableArray&amp;lt;T&amp;gt;.Empty&lt;/code&gt; vs &lt;code&gt;new T[0]&lt;/code&gt;) and amazingly do not provide value equality.&lt;/p&gt;
&lt;h3&gt;
  
  
  5) Pipe-forward operator
&lt;/h3&gt;

&lt;p&gt;So much C# code is just&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetThing&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;propertyOfThing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetProperty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="n"&gt;thatOtherThing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;transformedThing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyOfThing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While adding named variables can help with clarity, let's just face it, these were added here because a long chain of transforms looks bad as a single expression, e.g. &lt;code&gt;Transform(GetThing().GetProperty() ?? ...&lt;/code&gt; is not super readable. Even spread out over multiple lines, it's still a bit all over the place, with logic sometimes flowing left to right (&lt;code&gt;thing.GetProperty() ?? thatOtherThing&lt;/code&gt;) and sometimes right to left (&lt;code&gt;Transform(propertyOfThing)&lt;/code&gt;). The F# pipe operator fixes all of that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it alleviates the need for trivial variable names&lt;/li&gt;
&lt;li&gt;it lets the logic flow left to right, top to bottom, the way we naturally read text&lt;/li&gt;
&lt;li&gt;and it promotes free functions
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GetThing&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GetProperty&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt; &lt;span class="n"&gt;thatOtherThing&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Transform&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The closest thing C# offers is fluent APIs.&lt;/p&gt;

&lt;p&gt;Now this one &lt;em&gt;might&lt;/em&gt; theoretically happen for C#; &lt;a href="https://github.com/dotnet/csharplang/discussions/96"&gt;it has actually been discussed for a long a time&lt;/a&gt;. JavaScript, a language much closer to C# than F#, is very seriously considering it (see tc39). However, I would not count on this happening for a long while.&lt;/p&gt;

</description>
      <category>fsharp</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Comparing IAsyncEnumerable and IObservable for event streams</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Wed, 23 Feb 2022 16:15:22 +0000</pubDate>
      <link>https://dev.to/asik/comparing-iasyncenumerable-and-iobservable-for-event-streams-5g96</link>
      <guid>https://dev.to/asik/comparing-iasyncenumerable-and-iobservable-for-event-streams-5g96</guid>
      <description>&lt;p&gt;I spent a day experimenting with both approaches for representing and manipulating streams of events and here are some preliminary thoughts. &lt;/p&gt;

&lt;h2&gt;
  
  
  Similarities
&lt;/h2&gt;

&lt;p&gt;Both can represent a stream of events or messages.&lt;/p&gt;

&lt;p&gt;Both define LINQ-style operators like &lt;code&gt;Select&lt;/code&gt;, &lt;code&gt;Where&lt;/code&gt; and  &lt;code&gt;Aggregate&lt;/code&gt;, making it easy to manipulate the streams.&lt;/p&gt;

&lt;p&gt;Both allow merging two streams into one. Note that at the time of writing, the appropriate method for this with &lt;code&gt;IAsyncEnumerable&lt;/code&gt; is &lt;code&gt;AsyncEnumerableEx.Merge&lt;/code&gt; from &lt;a href="https://www.nuget.org/packages/System.Interactive.Async/" rel="noopener noreferrer"&gt;System.Interactive.Async&lt;/a&gt;, &lt;em&gt;not&lt;/em&gt; the extension method of the same name, &lt;a href="https://github.com/dotnet/reactive/blob/ab72daabc11b39ddfb234fa24799aff0ad740f9b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Merge.cs#L319" rel="noopener noreferrer"&gt;which behaves differently&lt;/a&gt;, concatenating the input streams rather than interweaving their results as they arrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;IAsyncEnumerable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It's a pull model: items are created on request as the consumer iterates the stream, just like with &lt;code&gt;IEnumerable&lt;/code&gt;. This implies that there needs to be some buffering between where your events are produced (e.g. from the real world, from a message broker, etc.) and when they are consumed. &lt;code&gt;System.Threading.Channels.Channel&lt;/code&gt; is designed to fulfill this need.&lt;/p&gt;

&lt;p&gt;Has strong traction in the dotnet ecosystem, with language integration in C#8 both for consuming (&lt;code&gt;await foreach&lt;/code&gt;) and producing (transforming &lt;code&gt;async IAsyncEnumerable&lt;/code&gt; functions into async iterator generators). &lt;code&gt;System.Threading.Channels&lt;/code&gt; is a currently recommended approach (&lt;a href="https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/" rel="noopener noreferrer"&gt;source&lt;/a&gt;) for producer/consumer scenarios.&lt;/p&gt;

&lt;p&gt;Integrates well with async/await.&lt;/p&gt;

&lt;p&gt;Encourages an imperative style: the language integration consists of a foreach loop, which means mutable state. That said, it's easy to define additional extension methods to allow writing in a more functional style. Here's an equivalent of &lt;a href="https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-listmodule.html#choose" rel="noopener noreferrer"&gt;F#'s choose&lt;/a&gt; for &lt;code&gt;IAsyncEnumerable&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Choose&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IAsyncEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TSource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TResult&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;IEnumerable&lt;/code&gt; and &lt;code&gt;Task&lt;/code&gt; are two concepts most C# developers interact with on a daily basis, so the combination of the two should be fairly intuitive.&lt;/p&gt;

&lt;p&gt;Support for F# &lt;a href="https://github.com/fsharp/fslang-design/blob/main/RFCs/FS-1101-asyncseq-builder.md" rel="noopener noreferrer"&gt;is planned&lt;/a&gt;, in the form of &lt;code&gt;taskSeq&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;IObservable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It's a push model, similar to C# events: you subscribe a synchronous handler and it gets called whenever an event happens. If you have asynchronous work to do in response to the event, you could convert its output to another &lt;code&gt;IObservable&lt;/code&gt;; this approach is described &lt;a href="https://github.com/dotnet/reactive/issues/459#issuecomment-357648243" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The &lt;code&gt;IObservable&amp;lt;-&amp;gt;Task&lt;/code&gt; interop story seems solid, but the back-and-forth seems like an unavoidable point of friction. &lt;code&gt;Task&lt;/code&gt; is a pull model; &lt;code&gt;IObservable&lt;/code&gt; is a push model. &lt;code&gt;Task&lt;/code&gt; permeates more and more of the dotnet ecosystem every year, it seems, for better or worse.&lt;/p&gt;

&lt;p&gt;Documentation on how to create Observables and Observers is surprisingly hard to find. ReactiveX, the open-source project, has a high-level, language-agnostic &lt;a href="https://reactivex.io/documentation/observable.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, which is not enough to fully understand how to use Rx.Net specifically.&lt;/p&gt;

&lt;p&gt;The MSDN documentation exists, but is above 10 years old and not currently maintained.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fucvp1bryv45ils8by8x0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fucvp1bryv45ils8by8x0.png" alt="Image description" width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Googling for examples yields mostly results for RxJS or RxJava. Blog posts or SO questions tend to date 5-10 years, which doesn't necessarily make them &lt;em&gt;wrong&lt;/em&gt; today, but means they're not taking into account the current state of the dotnet ecosystem.&lt;/p&gt;

&lt;p&gt;Admittedly, the story isn't that great for &lt;code&gt;IAsyncEnumerable&lt;/code&gt; documentation either: googling &lt;code&gt;AsyncEnumerable.ToArrayAsync&lt;/code&gt; sends me to &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.query.asyncenumerable-1.toarrayasync?view=efcore-2.2" rel="noopener noreferrer"&gt;Entity Framework documentation&lt;/a&gt; and if the real doc for &lt;code&gt;System.Linq.AsyncEnumerable&lt;/code&gt; exists anywhere, let me know.&lt;/p&gt;

&lt;p&gt;The thing is, I don't need to form a new conceptual model to understand what &lt;code&gt;ToArrayAsync&lt;/code&gt; is going to do, or what &lt;code&gt;await foreach&lt;/code&gt; will do. To use &lt;code&gt;IObservable&lt;/code&gt;, I need to understand new terminology such as hot vs cold observables, what &lt;code&gt;Publish&lt;/code&gt; does, what &lt;code&gt;Subscribe&lt;/code&gt; does, what a &lt;code&gt;Subject&lt;/code&gt; is and when should I use it; how to avoid deadlocks which are reportedly easy to run into; how and when to properly call OnNext/OnError/OnCompleted - should I use try-catch-finally on all my logic to make sure I call these reliably? What really happens when exceptions are thrown, are they just propagated or do they stop the stream? I need guidance and best practices if I'm to introduce a new library to a team project, especially one with a high learning curve and deadly gotchas, and the fact that I, or colleagues on my team, can't refer to an official up-to-date doc means this is probably a no-go.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;Well, I meant to write an objective pro/cons list, but this turned out into a long rant against &lt;code&gt;IObservable&lt;/code&gt;, didn't it? The fact is, the push model appeals to me and seems very powerful. Rx makes it easy to define and manipulate streams of events, and if I could find the time to learn it properly, I feel like it could help me come up with even more elegant solutions than what &lt;code&gt;Channel&lt;/code&gt;s and async streams allow. The fundamental issue is that the &lt;code&gt;Task&lt;/code&gt;-based, pull model seems to have slowly taken over everything in dotnet in the past decade. With &lt;code&gt;IAsyncEnumerable&lt;/code&gt; having language integration in C# and little in the way of new concepts, it's very hard to argue for a competing model, especially without proper guidance and documentation for that model.&lt;/p&gt;

&lt;p&gt;That said, this was the result of a single day of investigation, so keep in mind this is a pretty superficial overview. I look forward to deepening my understanding of this topic in the future.&lt;/p&gt;

&lt;p&gt;Further reading:&lt;br&gt;
A good discussion of async pull vs IObservable: &lt;a href="https://fsprojects.github.io/FSharp.Control.AsyncSeq/AsyncSeq.html" rel="noopener noreferrer"&gt;https://fsprojects.github.io/FSharp.Control.AsyncSeq/AsyncSeq.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>eventdriven</category>
      <category>fsharp</category>
    </item>
    <item>
      <title>Don't make these 5 F# mistakes</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Tue, 14 Dec 2021 21:26:43 +0000</pubDate>
      <link>https://dev.to/asik/dont-make-these-5-f-mistakes-3626</link>
      <guid>https://dev.to/asik/dont-make-these-5-f-mistakes-3626</guid>
      <description>&lt;p&gt;I'm lucky enough to be working full-time at a company that uses F#, so here are some observations I compiled from doing code reviews on real-world codebases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Correctness:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Prefer &lt;code&gt;string&lt;/code&gt; to &lt;code&gt;.ToString()&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToString&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// throws System.NullReferenceException&lt;/span&gt;

&lt;span class="c1"&gt;// Safer ways to obtain a string representation:&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="c1"&gt;// ""&lt;/span&gt;
&lt;span class="s2"&gt;"${i}"&lt;/span&gt; &lt;span class="c1"&gt;// ""&lt;/span&gt;
&lt;span class="n"&gt;sprintf&lt;/span&gt; &lt;span class="s2"&gt;"%O"&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="c1"&gt;// "&amp;lt;null&amp;gt;"&lt;/span&gt;
&lt;span class="n"&gt;sprintf&lt;/span&gt; &lt;span class="s2"&gt;"%A"&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="c1"&gt;// "None"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Don't use &lt;code&gt;failwith&lt;/code&gt; or &lt;code&gt;failwithf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It throws &lt;code&gt;System.Exception&lt;/code&gt;: this violates &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/exceptions/creating-and-throwing-exceptions#things-to-avoid-when-throwing-exceptions"&gt;.NET Exception guidelines&lt;/a&gt;. From experience, it's can be very annoying to debug a project where you need to break on &lt;code&gt;System.Exception&lt;/code&gt;, as any random code can throw it.&lt;br&gt;
Defining your own exception type in F# is a &lt;a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/exception-handling/exception-types"&gt;one-liner&lt;/a&gt;, so do create your own exception types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DON'T:&lt;/span&gt;
&lt;span class="n"&gt;failwith&lt;/span&gt; &lt;span class="n"&gt;errorMessage&lt;/span&gt;

&lt;span class="c1"&gt;// DO&lt;/span&gt;
&lt;span class="k"&gt;exception&lt;/span&gt; &lt;span class="nc"&gt;OrderValidationException&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;raise&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderValidationException&lt;/span&gt; &lt;span class="n"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Style:
&lt;/h2&gt;

&lt;p&gt;Note that the code in the following examples is perfectly fine as-is.&lt;br&gt;
These are just opportunities to keep in mind to make the code easier to read.&lt;/p&gt;
&lt;h3&gt;
  
  
  3) Don't use &lt;code&gt;fst&lt;/code&gt; and &lt;code&gt;snd&lt;/code&gt;...
&lt;/h3&gt;

&lt;p&gt;... at least when a simple destructuring pattern would suffice. These are terribly named functions. You can't get anything but the 1st or 2nd element that way. It makes it hard to understand what was extracted unless the result is immediately bound to an identifier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="n"&gt;setupUnitTestMocks&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fst&lt;/span&gt;  &lt;span class="c1"&gt;// what's this??&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;testWith&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prefer destructuring, with the added bonus that this will look familiar to C# and JS programmers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ah it's a mock of a database&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;databaseMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;setupUnitTestMocks&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;testWith&lt;/span&gt; &lt;span class="n"&gt;databaseMock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4) Don't abuse lambdas
&lt;/h3&gt;

&lt;p&gt;F# makes it so easy and convenient to use pipe-to-lambda for everything that sometimes we forget we can use plain let bindings, match statements, for loops etc. Lambdas make code flow trickier to understand (what's the argument? what's being returned?).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;orderInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="nn"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NewGuid&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToString&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt; &lt;span class="n"&gt;validatedOrder&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validatedOrder&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;raise&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderCreationException&lt;/span&gt; &lt;span class="s2"&gt;"This should never happen"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;
          &lt;span class="nc"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Empty&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can reduce indentation and make this code easier to follow with a let binding, and replacing the &lt;code&gt;function&lt;/code&gt; with a &lt;code&gt;match&lt;/code&gt; statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;orderInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NewGuid&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToString&lt;/span&gt;&lt;span class="bp"&gt;()&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt; &lt;span class="n"&gt;validatedOrder&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;validatedOrder&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;_&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;raise&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderCreationException&lt;/span&gt; &lt;span class="s2"&gt;"This should never happen"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;
      &lt;span class="nc"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Empty&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5) Don't systematically add parentheses around function arguments
&lt;/h3&gt;

&lt;p&gt;This is a hard habit to get rid of coming from C-style languages, but function invocation is indicated by spacing, not parentheses.&lt;/p&gt;

&lt;p&gt;Systematic use of redundant parentheses make F# code slightly heavier than it needs to be.&lt;br&gt;
I want to stress that this is purely stylistic, but I suspect most F# programmers do this out of habit, not conscious thought.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// OK:&lt;/span&gt;
&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;OrderReceived&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;incomingOrder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Better:&lt;/span&gt;
&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nn"&gt;OrderReceived&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt; &lt;span class="n"&gt;incomingOrder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This includes constructors too, which are just functions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;orderReceivedCompletion&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="nc"&gt;TaskCompletionSource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;_&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;TaskCreationOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RunContinuationsAsynchronously&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Special thanks to Don Syme for reading this article and &lt;a href="https://twitter.com/dsymetweets/status/1471260583928418304"&gt;suggesting some improvements&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>fsharp</category>
      <category>codereview</category>
      <category>dotnet</category>
      <category>programming</category>
    </item>
    <item>
      <title>Did C#9 kill optional constructor parameters?</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Wed, 25 Aug 2021 17:48:47 +0000</pubDate>
      <link>https://dev.to/asik/67-cleaner-code-with-init-only-properties-17kh</link>
      <guid>https://dev.to/asik/67-cleaner-code-with-init-only-properties-17kh</guid>
      <description>&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/init"&gt;Init-only setters&lt;/a&gt;, introduced in C# 9, allow for a concise alternative to named optional constructor parameters. Let's illustrate and then discuss the pros and cons.&lt;/p&gt;

&lt;p&gt;As you can see in the example below, the amount of repetition involved in getting a private readonly field initialized with an optional constructor parameter (that's a mouthful, but it's a common thing to do) has traditionally been insane. I have to write the name of each field 4 times and specify their type twice to get a readonly optional field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onOpen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onBegin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onOpen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onClose&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onBegin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onOpen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onOpen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onClose&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onBegin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onBegin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// usage:&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OnClose called"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As it turns out, properties marked as &lt;code&gt;{ private get; init; }&lt;/code&gt; can fill the same role with no code repetition, cutting down clutter by two thirds!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;OnOpen&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;OnClose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;OnBegin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// usage:&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;C2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;OnClose&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OnClose called"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the getter is private, the property can only be accessed in the object initializer, making it equivalent, for our purposes, to a named optional constructor parameter.&lt;/p&gt;

&lt;p&gt;Since this class has no required constructor parameters, it can do away with a constructor entirely. This pattern could even work with required parameters in the future, if &lt;a href="https://github.com/dotnet/csharplang/issues/3630"&gt;required init-only properties&lt;/a&gt; make it into a future C# version, C# 10 or C# 11 perhaps? The syntax would hypothetically look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;OnOpen&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;OnClose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;OnBegin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// usage:&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;C2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;OnClose&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OnClose called"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;// compilation error: OnOpen must be provided&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 or 5 keywords per property is a bit intense to be sure, but I'd take it over the sheer massive boilerplate it replaces.&lt;/p&gt;

&lt;p&gt;I'm not sure at this point what the drawbacks would be. A couple I can see so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The property appears in code completion since it's public. It won't be possible to use it outside the object initializer, but this might be a bit confusing. This is more of a glitch of code completion than anything else.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// code completion will suggest OnClose at this point&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; 

&lt;span class="c1"&gt;// but it's inaccessible, so you just get a compiler error&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnClose&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c1"&gt;// code completion could be smarter, but that's what we have today&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;It creates a slight discoverability issue for the consumer, as all constructor parameters appear in code completion, but init-only properties only appear when opening an object initializer, which a user might just forget to do, or wonder how the object is to be used.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;// see list of constructor arguments appear&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;C2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;// code completion shows nothing at this point&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;C2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// only now you get your property names&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both of these issues mainly stem from unfamiliarity with the pattern, so I don't think they're necessarily roadblocks.&lt;/p&gt;

&lt;p&gt;What do you all think?&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>F#'s Stack Overflow community is amazing</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Wed, 09 Dec 2020 14:15:58 +0000</pubDate>
      <link>https://dev.to/asik/f-s-stack-overflow-community-is-amazing-51n6</link>
      <guid>https://dev.to/asik/f-s-stack-overflow-community-is-amazing-51n6</guid>
      <description>&lt;p&gt;I recently asked a question about F# syntax on Stack Overflow. It seemed like a weird edge case with indentation, and I did not expect many people to have encountered this; if they did, they were unlikely to know the answer as it would be quite technical. Still, I wanted to do due diligence before opening an issue on the F# compiler repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is just an alias of |&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;inline&lt;/span&gt; &lt;span class="o"&gt;(|&amp;gt;!)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;U&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;  

&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; 
    &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;!&lt;/span&gt; &lt;span class="n"&gt;printfn&lt;/span&gt; &lt;span class="s2"&gt;"%d"&lt;/span&gt; &lt;span class="c1"&gt;// FS0001: The type 'int' does not match the type 'unit'&lt;/span&gt;

&lt;span class="c1"&gt;// if you replace |&amp;gt;! with |&amp;gt; it compiles, even though&lt;/span&gt;
&lt;span class="c1"&gt;// it's literally the same operator&lt;/span&gt;
&lt;span class="c1"&gt;// seriously, who's going to know the answer to this&lt;/span&gt;
&lt;span class="c1"&gt;// or so I thought&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo and behold, &lt;a href="https://stackoverflow.com/questions/65148571/identical-syntax-is-invalid-when-using-a-user-defined-operator"&gt;it had already been asked&lt;/a&gt;, and already had a great, detailed answer by user &lt;a href="https://stackoverflow.com/users/180286/fyodor-soikin"&gt;Fyodor Soikin&lt;/a&gt;. He pointed me to it literally within minutes of my post. I was amazed. &lt;/p&gt;

&lt;p&gt;For the curious, a short version of it would be this. While a human reads the above as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;!&lt;/span&gt; &lt;span class="n"&gt;printfn&lt;/span&gt; &lt;span class="s2"&gt;"%d"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because my operator has 3 characters instead of 2, this pushes the &lt;code&gt;printfn&lt;/code&gt; one space, right under the &lt;code&gt;0&lt;/code&gt; above, and F# interprets it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; 
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="c1"&gt;// this is an int&lt;/span&gt;
&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;!&lt;/span&gt; &lt;span class="n"&gt;printfn&lt;/span&gt; &lt;span class="s2"&gt;"%d"&lt;/span&gt; &lt;span class="c1"&gt;// this is unit, so the types mismatch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that's not really the point of this blog post; see the linked question for the juicy technical details.&lt;/p&gt;

&lt;p&gt;I've had this experience several times now over my many years of using F#, where I'll ask something simple and then get an answer from someone like e.g. &lt;a href="https://stackoverflow.com/users/33518/tomas-petricek"&gt;Tomas Petricek&lt;/a&gt;, just to name one, with great thought and care, rigorous detail and technical clarity. The level of passion and knowledge demonstrated by many F# community members never ceases to impress me. Even compared to other great SO communities, F#'s feels more friendly, passionate and technically proficient.&lt;/p&gt;

&lt;p&gt;Coming from more mainstream languages, one might think moving to a smaller community would make it harder to find support. I think the F# community demonstrates that's not about quantity but quality.&lt;/p&gt;

</description>
      <category>fsharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Fixing a bug in the F# compiler</title>
      <dc:creator>André Slupik</dc:creator>
      <pubDate>Sun, 29 Nov 2020 16:37:12 +0000</pubDate>
      <link>https://dev.to/asik/fixing-a-bug-in-the-f-compiler-57eg</link>
      <guid>https://dev.to/asik/fixing-a-bug-in-the-f-compiler-57eg</guid>
      <description>&lt;p&gt;A couple weeks ago, a &lt;a href="https://github.com/dotnet/fsharp/pull/10510"&gt;PR of mine&lt;/a&gt; was merged into the F# compiler repo, fixing an issue that bothered me with unused &lt;code&gt;open&lt;/code&gt; statement detection. Even just a few years ago, this would have seemed like a daunting task to me, so this felt like a real achievement.&lt;/p&gt;

&lt;p&gt;A great motivator for me was to watch this relaxed, slow-moving presentation from Don Syme (the man himself), fixing a bug in the compiler live. It is filled with useful nuggets of information about the structure of the codebase and coding conventions, and that definitely helped me get around and understand what I was looking at. &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-dKf15xSWPY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I then read the available documentation, which is high quality: the &lt;a href="https://github.com/dotnet/fsharp/blob/main/README.md"&gt;README&lt;/a&gt;, the &lt;a href="https://github.com/dotnet/fsharp/blob/main/DEVGUIDE.md"&gt;DEVGUIDE&lt;/a&gt;, and the &lt;a href="https://fsharp.github.io/fsharp-compiler-docs/"&gt;Compiler Guide&lt;/a&gt;. I really appreciate that all this documentation is right there in the repo, it makes it easy to access, consume and update.&lt;/p&gt;

&lt;p&gt;Having worked with Github daily for about a year, I had become familiar with the PR process. Nonetheless, one mistake I made was to clone the actual &lt;code&gt;dotnet/fsharp&lt;/code&gt; repo instead of forking it and then cloning my fork; once I had the fix commited, I was unable to push it as, of course, I don't have the rights on &lt;code&gt;dotnet/fsharp&lt;/code&gt;. If that happens to you, it's easy to retarget your local repo to your fork with&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git remote set-url origin https://github.com/yourusername/yourfork.git&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Now you'll be able to &lt;code&gt;git push&lt;/code&gt; your changes as they'll go to your fork.&lt;/p&gt;

&lt;p&gt;I made the mistake of trying to debug the F# tools on the currently released Visual Studio. Currently, this requires &lt;a href="https://visualstudio.microsoft.com/vs/preview/"&gt;Visual Studio Preview&lt;/a&gt;, which can be installed side-by-side.&lt;/p&gt;

&lt;p&gt;I also got a &lt;a href="https://github.com/dotnet/fsharp/pull/10510#issue-524327963"&gt;mysterious error trying to run the tests&lt;/a&gt; but you can always run the tests directly on the compiled dll with &lt;code&gt;dotnet test &amp;lt;your test dll&amp;gt;&lt;/code&gt;. I also added &lt;code&gt;--verbosity detailed&lt;/code&gt; to get the result of each test printed to the console.&lt;/p&gt;

&lt;p&gt;Overall, I'm surprised the process was so straightforward for what is a large codebase with a long history. The F# tools definitely need some love, so I hope this helps someone out there trying to improve them.&lt;/p&gt;

</description>
      <category>fsharp</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
