<?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: Zenobio</title>
    <description>The latest articles on DEV Community by Zenobio (@zenobio).</description>
    <link>https://dev.to/zenobio</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%2F458419%2F56e34945-3477-41a7-bce7-6c4f53f22d72.jpeg</url>
      <title>DEV Community: Zenobio</title>
      <link>https://dev.to/zenobio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zenobio"/>
    <language>en</language>
    <item>
      <title>An unnecessary complexity tale on Typescript-land.</title>
      <dc:creator>Zenobio</dc:creator>
      <pubDate>Sat, 02 Apr 2022 05:39:13 +0000</pubDate>
      <link>https://dev.to/zenobio/an-unnecessary-complexity-tale-on-typescript-land-3j7d</link>
      <guid>https://dev.to/zenobio/an-unnecessary-complexity-tale-on-typescript-land-3j7d</guid>
      <description>&lt;p&gt;Twitter is both a blessing and a curse as anyone who's fond of the platform can attest to. Today, I've found a small challenge lurking within a tweet under a hashtag that I don't really follow or have any interest whatsoever but sometimes it pops up (???)...&lt;/p&gt;

&lt;p&gt;The challenger was really straight forward:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vyeakzve8duao9kazht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vyeakzve8duao9kazht.png" alt="oleg008 Tweet" width="501" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As someone who likes to keep the codebase with the small amount of &lt;code&gt;any&lt;/code&gt;'s possible, I clicked the &lt;a href="https://www.typescriptlang.org/play?ssl=22&amp;amp;ssc=1&amp;amp;pln=23&amp;amp;pc=1#code/C4TwDgpgBAwg9gO2AQwJYIgJwDwDVkA2ArhAHxQC8UA3gFBQNQBuhJAXFPsRLQL620AxogDOwKIMwRkwCPCRoMmSlDytoEAB6yEAExFQiCANYI4AdwSkAFC24cuJAJQd5KdFjXdyFcnUZQUsBEmAg0diT8-EKi4gBmKtbCCh6YIhwAgpiYyCDYboqeyAggpKQANBKEBABGyILGHNYAdK0REOlQxSBOlORMcKi6vb409IzJYszqBlQA2gC64wxxcMpJsRKI7kpQcAnJO1givf4BjO0izWBEIgAWGylKze1Oy1D8AYLVdQ0tbTM3tEYggpodCpgAIwqSTSWQFVLWADkd1QSLek3E4NSACYYVIZHJthDrDi3gIAPQUqAACQsUF0cCgAElAhAwAR6tBgHc4CJoN0oKBIAZ0F0oOZckK7jIJagCFAAOaoJjQAC2Gk09XEwo60240OKun1JBxlXMqB5cCI4hlTHQiqFTJEkEEqDiIGlEDVAH5aHFrHNsUpIZVg1gcQtKrZ1KGTRAyX0xnxyUA" rel="noopener noreferrer"&gt;playground link&lt;/a&gt; and gave it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  And... are those "Generics" with us in the room right now?
&lt;/h2&gt;

&lt;p&gt;My first idea was pretty simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;Starting with a Generic &lt;code&gt;T&lt;/code&gt; which needs to extends the &lt;code&gt;Container&lt;/code&gt; type to guarantee that the &lt;code&gt;containers&lt;/code&gt; parameter type is undoubtedly a &lt;code&gt;List of Containers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, how do we implement the type logic for &lt;code&gt;...values&lt;/code&gt; within the &lt;code&gt;callback&lt;/code&gt; parameter? After some time of weird thinking and listening to some City Pop, my &lt;em&gt;"amazing"&lt;/em&gt; head came up with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FromList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; 
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;Tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;FromList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Tail&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; 
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FromList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;I know, I know, a fully fledged display of unnecessary complexity. That's exactly why I said &lt;em&gt;"amazing"&lt;/em&gt;...&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;FromList&lt;/code&gt; type says that, given a &lt;code&gt;List&lt;/code&gt; of type &lt;code&gt;List of Containers of something&lt;/code&gt;, infer the type of this &lt;code&gt;something&lt;/code&gt;. The second validation says that, for this same given type &lt;code&gt;List of Containers of something&lt;/code&gt; destructure it as a &lt;a href="https://tsplay.dev/NBj34N" rel="noopener noreferrer"&gt;Tuple&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since &lt;em&gt;tuples&lt;/em&gt; are only lists with fixed size and known types (Weirdly close to a indexed type, don't you think so?), you can ask for this type expansion to infer the type of the first &lt;code&gt;something&lt;/code&gt; within the &lt;code&gt;Container&lt;/code&gt; type at the first index of this tuple while also using the spread operator to create a &lt;code&gt;Tail&lt;/code&gt; with the remaining types.&lt;/p&gt;

&lt;p&gt;If the first validation fails, it will return a &lt;code&gt;never&lt;/code&gt;, a type that could not be constructed. In case it succeeds we enter the second validation. For the second validation if it fails we will just return the type of the first validation because this isn't a "tuple" it's exactly a &lt;code&gt;List of Container of something&lt;/code&gt; and we just want this &lt;code&gt;something&lt;/code&gt; to be our type. In case it succeeds, we will recursively create a &lt;code&gt;Union&lt;/code&gt; which consists of the inferred type of the first &lt;code&gt;something&lt;/code&gt; or the reduced type of subsequent &lt;code&gt;FromList&lt;/code&gt; called with the inferred &lt;code&gt;Tail&lt;/code&gt; type.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's not quite right, isn't it?
&lt;/h2&gt;

&lt;p&gt;If you have spent some time playing with those custom utility types in TS then you're probably aware of the problem already.&lt;/p&gt;

&lt;p&gt;Adding this same logic to the playground we can see that first of all, TS is not happy. He's saying;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="nx"&gt;Argument&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unknown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;assignable&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;parameter&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FromList&amp;lt;T[]&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's because we didn't gave a type to the &lt;code&gt;values&lt;/code&gt; array which is being filled and used as parameter for our &lt;code&gt;callback&lt;/code&gt; function. And since we typed our &lt;code&gt;containers&lt;/code&gt; parameter as &lt;code&gt;T[]&lt;/code&gt; and &lt;code&gt;T&lt;/code&gt; is extending a &lt;code&gt;Container of unknown&lt;/code&gt;, we pretty much have no way to type it correctly without using type coercions which I tend to only use on cases where I have no alternatives.&lt;/p&gt;

&lt;p&gt;The second problem is that we're returning a &lt;code&gt;Union type&lt;/code&gt; from our &lt;code&gt;FromList&lt;/code&gt; and that will be the type of each and every single one of our parameters within the &lt;code&gt;callback&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// value1 is of type string | number&lt;/span&gt;
&lt;span class="c1"&gt;// value2 is of type string | number&lt;/span&gt;
&lt;span class="c1"&gt;// Any value within the callback will be this union type...&lt;/span&gt;
&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;container1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;container2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;We need a way to know exactly which are the types that are being held by every &lt;code&gt;Container&lt;/code&gt; in every index of our &lt;code&gt;containers&lt;/code&gt; parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing the Complexity
&lt;/h2&gt;

&lt;p&gt;First I want to mention that even though I've spent some time and have also used the destructured tuple in my first complex idea, I wasn't really able to move forward from there. &lt;/p&gt;

&lt;p&gt;After this &lt;code&gt;Union&lt;/code&gt; type I knew that an indexed type was necessary so it would be easier to retrieve the &lt;code&gt;something&lt;/code&gt; within each &lt;code&gt;Container&lt;/code&gt; for the given &lt;code&gt;key&lt;/code&gt; but I wasn't able to translate it into the correct idea. Lack of experience in a case like that I assume.&lt;/p&gt;

&lt;p&gt;I went back to the same tweet to check how people where implementing or at least how they where thinking about the problem. Found some interesting points of view but the one that caught my attention was &lt;a href="https://tsplay.dev/w24Rxm" rel="noopener noreferrer"&gt;this one&lt;/a&gt; from &lt;a href="https://twitter.com/devanshj__" rel="noopener noreferrer"&gt;devanshj__&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Mainly because of this line;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Changing the nomenclature for consistency&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;If you destructure the &lt;code&gt;T&lt;/code&gt; as a tuple as the type for the &lt;code&gt;containers&lt;/code&gt; parameter, TS will be able to infer which are the types in each and every index of it.&lt;/p&gt;

&lt;p&gt;Who knows why but my head wasn't capable of thinking in use the tuple this way. So, I went and updated my utility custom type to the same of the above example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PickFromContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;CT&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;CT&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PickFromContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;This &lt;code&gt;PickFromContainer&lt;/code&gt; type says; given a type &lt;code&gt;C&lt;/code&gt; (our tuple), for each of their keys (indexes), we will check if the type in that index is of type &lt;code&gt;Container of Something&lt;/code&gt; and if it is, we will ask TS to infer this &lt;code&gt;something&lt;/code&gt; for us and return it as the type within the index being mapped.&lt;/p&gt;

&lt;p&gt;That's beautiful and works like a charm. If you place that on the playground you'll see that every param on the &lt;code&gt;callback&lt;/code&gt; function is the same type &lt;code&gt;something&lt;/code&gt; as the &lt;code&gt;Container of something&lt;/code&gt; in that position based on the &lt;code&gt;containers&lt;/code&gt; parameter order.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But wait... Typescript is screaming at me again?&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Argument&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unknown[]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;assignable&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;parameter&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PickFromContainer&amp;lt;T&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeah, pretty much the same, since our type &lt;code&gt;T&lt;/code&gt; is necessarily a &lt;code&gt;List of Containers of Unknown&lt;/code&gt; and we're pushing a bunch of &lt;code&gt;Unknown&lt;/code&gt; to &lt;code&gt;values&lt;/code&gt;, it's  only fair that TS would consider the type of &lt;code&gt;values&lt;/code&gt; as a &lt;code&gt;List of Unknown&lt;/code&gt; and when we call our &lt;code&gt;callback&lt;/code&gt; function with this list as a parameter, the &lt;code&gt;PickFromContainer&lt;/code&gt; will not overlap the &lt;code&gt;List of Unknown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The only two things that can be assigned to &lt;code&gt;unknown&lt;/code&gt; are &lt;code&gt;any&lt;/code&gt; and &lt;code&gt;unknown&lt;/code&gt; itself and that leaves us with two ways to make TS happy right now.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Be rude and say: "I don't care, it can be anything!" and Coerce the &lt;code&gt;values&lt;/code&gt; list to &lt;code&gt;any&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Be kind and say: "Hey Typescript, I know that &lt;code&gt;values&lt;/code&gt; is &lt;code&gt;unknown&lt;/code&gt; to you but I also know that it will be a &lt;code&gt;PickFromContainer&lt;/code&gt; when needed".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From the start my idea was to remove &lt;code&gt;any&lt;/code&gt;'s so I'm going with the second approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PickFromContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PickFromContainer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;containers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&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;That's not my favorite approach, as mentioned before. We could have used a different approach with type predicates and let the compiled part of JS optimize it on its own but let's keep it simple and tell TS to believe us in this case. &lt;a href="https://www.typescriptlang.org/play?#code/C4TwDgpgBAwg9gO2AQwJYIgJwDwBUB8UAvFAN5QBuyANgK4QBcUuUAvgNwBQnAxogM7AoPTBGTAI8JGgyZiUPABp8ACip1GzAJRMpKdFjyEihUpygWoo4LUwIylGvTadW3UJCgAFVDwDWAGKYcAC2ejKGMMZkANoA0lDoUH4QIHAAZrAAurrxWVAQAB4SCAAm-LCI+rLY6OlYsARQAPyNUEwYFFgc3HwIglCZJHgFxRBlFeEGOLQIfghwAO4I+DFZquaWfdVY-EwxAHRHuFmKmxY8NNQARsj+TCpHB+r0e96+gcFhVRE4BFrEQgUOCoUqcAEmMjnYQCIQvCAVEhrKDICqzeZLeyo97+IKhKY1AhcSyDOByFR9AbbX5QDIw6TTfgAswkknw-gHMC0fgACwpP2mzycEC00LcJMu1Budz8jyO7NFbl4sPpO0wAEZ5CIxBICVgVAByHmoA2iylCanTABMWtE4kkAtkKitos4AHo3VAABJLKClOBQACSVggYGod2gwB5cH40GQCBAUA8CMSWKgi2Qiaj4nTqGoUAA5qgulAQtAinchMmKvDNfHSo4NFbFLmo3BaEIecgKOgC0mA-xIDxUOkszyICFmpx0ioYpbZOqW-OsFbTlA1MLF436C7AVDXFogA" rel="noopener noreferrer"&gt;Here's the playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Typescript doesn't really need to be complicated - Even though it is in some cases. Sometimes we add unnecessary complexity to things and everyone have done it at least once.&lt;/p&gt;

&lt;p&gt;Look at other developers ideas and their implementations is a really good way to improve yours. Just don't copy and paste everything, try to understand the &lt;em&gt;why&lt;/em&gt;'s and &lt;em&gt;when&lt;/em&gt;'s, because that how you'll be able to improve and derive from it when necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; It has been quite some time since I last saw this code and I did tried one or two extra tricks that I've learned throughout the way and it was enough to get rid of the type casting at the end. Please feel free to take a look on how I would implement the same thing today. &lt;a href="https://www.typescriptlang.org/play/?#code/C4TwDgpgBAwg9gO2AQwJYIgJwDwBUB8UAvFAN5QBuyANgK4QBcUuUAvgNwBQnAxogM7AoPTBGTAI8JGgyZiUPABp8ACip1GzAJRMpKdFjyEihUpygWoo4LUwIylGvTadW3UJCgAFVDwDWAGKYcAC2ejKGMMYOANoA0lDoUH4QIHAAZrAAurrxWVAQAB4SCAAm-LCI+rLY6OlYsARQAPyNUEwYFA0c3HwIgon84QaYAGpO0CRKqtSogky4OlCzA3NQAKKFPHSlEEpQtAh+CHAA7ggxWcaEAIKYmMggAHRzdw8gKivAWlAAZL9QACEgK+T2oEAQAHNgAALLi8ARCTJTFhFErlSrSEbYQ7HM4IfCXVTmSx9apYfhMGJPGm4LKKEkWHg0agAI2Q-iYKhpT3U9Ep3l8gWCYSqERwBB+JkocFQpU4UtMjOEiMcGgFuJO50uUAAPoL-EFQsMak0SJd4ZZEukVG9Hi9+HaPnyIPwtD8zFarek4HIVH0BmTxVAMiqsbI3WRlV7LC7+E8wLR+DD-WKRryJlpo5Y3Fbc5ZlXMTVhxho1BNI-9hCz2f5uTS41m3Aj+kIgyMAIzyERiCTFzAqADkMNQg6zAbbadkACZu6JxJIp1gVNOs5wAPTrqAACTOUFKcCgAEkrBAwNQOdBYXB+NBkAgQFAPK7EvZkFBTo8nzDxB-UNQoEhVAuigEJoCKDkhGfCoXS7e9SjVehp0UP9r1oIQfwodBISfQ9+EgHhUHSR9YQgEJmk4G0YnbWQOxQmisGnekoHLDQ6MQiBV2IJVXC0IA" rel="noopener noreferrer"&gt;Here's the playground link.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Trying your luck with Elm</title>
      <dc:creator>Zenobio</dc:creator>
      <pubDate>Sun, 20 Mar 2022 20:50:35 +0000</pubDate>
      <link>https://dev.to/zenobio/trying-your-luck-with-elm-26bc</link>
      <guid>https://dev.to/zenobio/trying-your-luck-with-elm-26bc</guid>
      <description>&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Boilerplate&lt;/li&gt;
&lt;li&gt;Baby Steps and Generators&lt;/li&gt;
&lt;li&gt;Look at my dice, my dice is amazing!&lt;/li&gt;
&lt;li&gt;Roll the Dice&lt;/li&gt;
&lt;li&gt;Final Considerations&lt;/li&gt;
&lt;li&gt;TL:DR&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Some time ago I was going through interviews for multiple companies and as pretty much every developer, I've been through some weird but also some funny and thoughtful ones.&lt;/p&gt;

&lt;p&gt;This one was on the thoughtful side and gave me some considerations while also confirmed thoughts I had from a time where I was the one interviewing.&lt;/p&gt;

&lt;p&gt;The test was really simple;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Implement a web app that rolls a dice with a button click and show the face with the correct number to the user."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, nothing that complex but it was funny to implement in Elm and I thought it might be good to share it for the sake of describing step by step my implementation for anyone who's trying to grasp a little bit more about the language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boilerplate I guess... &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The first thing would be prepare the boilerplate. I won't assume you have any previous experience with Elm, will try my best to explain my thought process here from the ground up, let's go from the most basic steps then.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="kt"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;Import&lt;/span&gt; &lt;span class="kt"&gt;Random&lt;/span&gt;

&lt;span class="c1"&gt;-- MAIN&lt;/span&gt;


&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subscriptions&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;-- MODEL&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- UPDATE&lt;/span&gt;


&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NoOp&lt;/span&gt;


&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;NoOp&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;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- SUBSCRIPTIONS&lt;/span&gt;


&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Sub&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;subscriptions&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="kt"&gt;Sub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dissecting the boilerplate we have a &lt;code&gt;main&lt;/code&gt; as the entry point that calls the &lt;code&gt;init&lt;/code&gt; function with a &lt;code&gt;Model&lt;/code&gt; that is just a empty Record that will be passed to the &lt;code&gt;view&lt;/code&gt; function which will only render a &lt;code&gt;div&lt;/code&gt; element with a &lt;code&gt;Hello World&lt;/code&gt; text as its content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Baby Steps and Generators &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have the boilerplate let's continue with baby steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;How will we think about implementing this "dice face randomizer"?.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, I tend to think towards&lt;br&gt;
&lt;em&gt;Behavior -&amp;gt; Visualization | UI -&amp;gt; Polishing&lt;/em&gt; and I'll be following those steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;But what can we consider as behavior?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I see "generate a random number within a button click" as the basic behavior of this problem. We can implement this with a &lt;a href="https://package.elm-lang.org/packages/elm/random/latest/Random#Generator" rel="noopener noreferrer"&gt;Generator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In Elm you cannot call a &lt;code&gt;Math.random&lt;/code&gt; the same way you can call in Javascript. It is a non deterministic behavior and as such it should be correctly handled by Elm in a slightly different way to achieve what we want. Taking a look on the documentation for the &lt;code&gt;Random&lt;/code&gt; module it's possible to see the example below that encapsulates pretty much what we need to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;NewNumber&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;

&lt;span class="n"&gt;newNumber&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;newNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="kt"&gt;NewNumber&lt;/span&gt; &lt;span class="n"&gt;oneToTen&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;em&gt;But what does this example says exactly?.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It says that you can call a &lt;code&gt;Random.generate&lt;/code&gt; with two arguments, a function that returns a &lt;code&gt;Msg&lt;/code&gt; type and a &lt;code&gt;Generator&lt;/code&gt; of some type so it can return a &lt;code&gt;Cmd Msg&lt;/code&gt; for you. Regarding the type annotations and the basics of how it works I think the &lt;a href="https://package.elm-lang.org/packages/elm/random/1.0.0/Random" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; can explain it better than I'll ever be able to so please take a look for more in depth details.&lt;/p&gt;

&lt;p&gt;We know from the documentation that &lt;code&gt;Random.generate&lt;/code&gt; can create a &lt;code&gt;Cmd Msg&lt;/code&gt; for us but we don't have anything useful for that in our &lt;code&gt;Msg&lt;/code&gt; type yet, so, lets implement it to receive a randomized number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Rolled&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;

&lt;span class="n"&gt;oneToSix&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Generator&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;oneToSix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a useful &lt;code&gt;Msg&lt;/code&gt; but that's not enough, as you might remember the &lt;code&gt;Random.Generator&lt;/code&gt; we have here is not something we can attach to our &lt;code&gt;Msg&lt;/code&gt; type. It will not work since &lt;code&gt;Rolled&lt;/code&gt; receives an &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;oneToSix&lt;/code&gt; is of type &lt;code&gt;Random.Generator Int&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;oneToSix&lt;/code&gt; generator need to be called to really &lt;em&gt;"generate"&lt;/em&gt; the value. That's a side effect and for that we need to ask Elm to perform it for us. So, now we need to use the &lt;code&gt;Random.generate&lt;/code&gt; to generate a &lt;code&gt;Cmd&lt;/code&gt; that Elm will gladly perform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;rollDice&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;rollDice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="kt"&gt;Rolled&lt;/span&gt; &lt;span class="n"&gt;oneToSix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's nice, now we have a &lt;code&gt;Cmd&lt;/code&gt; that Elm can perform and pass the value to our &lt;code&gt;Msg&lt;/code&gt; type which will gladly update our number. Update? Do we have this update logic in place? I don't think so...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;=&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="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Rolled&lt;/span&gt; &lt;span class="n"&gt;newValue&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;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Now I think we're covered. Our &lt;code&gt;init&lt;/code&gt; function was updated to initialize the &lt;code&gt;Model&lt;/code&gt; with a default value of &lt;code&gt;1&lt;/code&gt;, the &lt;code&gt;Model&lt;/code&gt; is holding a value to be rendered and the &lt;code&gt;update&lt;/code&gt; function is receiving the &lt;code&gt;newValue&lt;/code&gt; which will be generated by the &lt;code&gt;rollDice&lt;/code&gt; command right?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately not. Since &lt;code&gt;rollDice&lt;/code&gt; is a command we need a way to trigger that and say "Hey Elm, perform this action for me".&lt;/p&gt;

&lt;p&gt;If we look closely to the &lt;code&gt;update&lt;/code&gt; function we can see that it returns a tuple with &lt;code&gt;( Model, Cmd Msg )&lt;/code&gt;, the type signature for our &lt;code&gt;rollDice&lt;/code&gt; is a &lt;code&gt;Cmd Msg&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Why not put this here on our &lt;code&gt;update&lt;/code&gt; function since that's the way Elm transitioning from one model state to the other? Should I put that on the &lt;code&gt;Rolled&lt;/code&gt; scope?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put the &lt;code&gt;rollDice&lt;/code&gt; command in the returned tuple from the &lt;code&gt;Rolled&lt;/code&gt; Msg will trigger, every time this message have been triggered, the &lt;code&gt;rollDice&lt;/code&gt; command. But &lt;code&gt;rollDice&lt;/code&gt; calls &lt;code&gt;Rolled&lt;/code&gt; and it will create a loop that freezes your application.&lt;/p&gt;

&lt;p&gt;The correct way is to create a second &lt;code&gt;Msg&lt;/code&gt; that will say "Hey Elm, call &lt;code&gt;rollDice&lt;/code&gt; to me". That way the &lt;code&gt;Random.generate&lt;/code&gt; can call the &lt;code&gt;Rolled&lt;/code&gt; without creating a loop within our &lt;code&gt;update&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Rolled&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;NewNumber&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Rolled&lt;/span&gt; &lt;span class="n"&gt;newValue&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;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kt"&gt;NewNumber&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;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rollDice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the only missing piece is to be able to click a button to generate this number and see the number on the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&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="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&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="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;br&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;NewNumber&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Randomize"&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;Here we need to use &lt;code&gt;String.fromInt&lt;/code&gt; since the type of the &lt;code&gt;value&lt;/code&gt; variable is &lt;code&gt;Int&lt;/code&gt; and the &lt;code&gt;Html.text&lt;/code&gt; function receives a &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can click &lt;a href="https://ellie-app.com/gVTgNfKcVFba1" rel="noopener noreferrer"&gt;here&lt;/a&gt; to check the app till this point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Look at my dice, my dice is amazing! &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have our generator in place and we can see that it is working, it's time to start to move from the abstract behavior to the more concrete idea of a dice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A dice face is made of dots and spaces between those dots.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's not so helpful isn't it? We need a way to check how those dots are distributed for each one of the its faces. Just like this next picture.&lt;/p&gt;

&lt;p&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%2Fs6s5r8d7jrt3ie44n9il.jpeg" 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%2Fs6s5r8d7jrt3ie44n9il.jpeg" alt="Dice faces" width="800" height="517"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now that's helpful. We can see that the dots have a distribution that is possible to be described as lines and columns. The best way to visualize that is as if we had a Rubik's cube where every single face is white and we can paint black some of the pieces that compose each face to describe one of the dice faces.&lt;/p&gt;

&lt;p&gt;Thats a good metaphor but you have to understand that it is mostly a description of a 3x3 matrix (Same as each single face of the Rubik's cube) and following that we will implement a matrix representation using lists to render our amazing dice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;renderDot&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;renderDot&lt;/span&gt; &lt;span class="n"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;dotClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;visible&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
              &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dot"&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
              &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dot__invisible"&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;dotClass&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&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="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;renderRow&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;lst&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;renderDot&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dots-row"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&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;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;renderRow&lt;/span&gt;

        &lt;span class="n"&gt;renderDice&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dice-container"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dice"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;renderDice&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button-container"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;NewNumber&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Roll The Dice"&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;Here we're creating a really simple &lt;code&gt;renderDot&lt;/code&gt; function that receives a boolean flag and if its &lt;code&gt;True&lt;/code&gt; the dot will be rendered as a black spot otherwise it will be rendered as transparent so we can have the correct spacing between dots.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;view&lt;/code&gt; function got a little more weird but isn't that complex. We have a &lt;code&gt;main&lt;/code&gt; div and inside that we have two containers. First one holding the &lt;code&gt;renderDice&lt;/code&gt; function that returns a &lt;code&gt;Html Msg&lt;/code&gt; and thus a valid children. The second container holds the button to roll the dice.&lt;/p&gt;

&lt;p&gt;Within the &lt;code&gt;let...in&lt;/code&gt; scope we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;renderDice&lt;/code&gt;: A function that receives an argument but currently ignores it and return a &lt;code&gt;Html Msg&lt;/code&gt;, our &lt;code&gt;dice-container&lt;/code&gt; with the &lt;code&gt;dice&lt;/code&gt; as its direct children.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rows&lt;/code&gt;: A value that calls &lt;code&gt;renderRow&lt;/code&gt; passing a representation of a 3x3 matrix.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;renderRow&lt;/code&gt;: A function that receives a list of boolean flag and maps every element to our &lt;code&gt;renderDot&lt;/code&gt; function creating at the end a list of &lt;code&gt;Html Msg&lt;/code&gt;. In that case a row containing a representation of three dots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check the current state of the implementation and the whole CSS necessary to render the UI &lt;a href="https://ellie-app.com/gYKMSTVc6NDa1" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Please take your time to understand if needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roll the Dice &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The missing piece right now is connect our current functions in a way that we can check which number renders which face.&lt;/p&gt;

&lt;p&gt;Lets firstly check what we already have that could be useful so we don't get lost within multiple moving parts.&lt;/p&gt;

&lt;p&gt;Do you recall our &lt;code&gt;renderRow&lt;/code&gt; function and our &lt;code&gt;rows&lt;/code&gt; value? Let's move then out of the &lt;code&gt;let...in&lt;/code&gt; scope so we can re-use them to build the rows automatically for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;generateDotsFromMatrix&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;generateDotsFromMatrix&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;generateDotsRow&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;generateDot&lt;/span&gt;
                &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dots-row"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;generateDotsRow&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dice__content"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have changed our previous &lt;code&gt;rows&lt;/code&gt; value to a &lt;code&gt;generateDotsFromMatrix&lt;/code&gt;, a function that receives our matrix representation and returns the content of the dice. We also renamed the &lt;code&gt;renderRow&lt;/code&gt; function to &lt;code&gt;generateDotsRow&lt;/code&gt; which describes what the function does in a more clear way and renamed &lt;code&gt;renderDot&lt;/code&gt; function to &lt;code&gt;generateDot&lt;/code&gt; for the same reason. &lt;/p&gt;

&lt;p&gt;That's it, only a matter of grounding some moving parts to ease our transition to a more reusable logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;What about the other faces? This dice only renders one face...&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're right, let's fix that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="n"&gt;renderDice&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;dots&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;generateTruesFromMatrix&lt;/span&gt; 
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;generateTruesFromMatrix&lt;/span&gt; 
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;generateTruesFromMatrix&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;generateTruesFromMatrix&lt;/span&gt; 
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;generateTruesFromMatrix&lt;/span&gt;
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="n"&gt;generateTruesFromMatrix&lt;/span&gt; 
                        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;True&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;False&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&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;in&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dice-container"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dice"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;dots&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&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="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;renderDice&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button-container"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;NewNumber&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Roll The Dice"&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;Updating our function &lt;code&gt;renderDice&lt;/code&gt;, using pattern match to map from all the possible given values to the correct matrix that represents the combination of black and transparent dots for a given dice face.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;That's it, right, a fully fledged "Roll the dice" app!!.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yeah, if you only consider what was asked for, that's it.&lt;/p&gt;

&lt;p&gt;But what if, for some reason, someone touches your &lt;code&gt;renderDice&lt;/code&gt; function and changed some flags. Will be hard to track those changes just by looking at it right?. A flag doesn't mean anything by itself we can just change the &lt;code&gt;renderDot&lt;/code&gt; function to do the opposite and voila all the app logic breaks and we will not understand easily because only the &lt;code&gt;if...else&lt;/code&gt; was swapped and that's why using those boolean flags isn't a good idea. It's time to do some changes in order to keep us sane if we ever need to touch this code again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Dot&lt;/span&gt; 
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Dot&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt; 

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;generateDot&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Dot&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;generateDot&lt;/span&gt; &lt;span class="n"&gt;mDot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt;
        &lt;span class="n"&gt;cls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;mDot&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
                &lt;span class="kt"&gt;Dot&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dot"&lt;/span&gt;
                &lt;span class="kt"&gt;Placeholder&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
                    &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dot__invisible"&lt;/span&gt;
    &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;cls&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;generateDotsFromMatrix&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="kt"&gt;Dot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="c1"&gt;-- Implementation remains untouched...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Created a &lt;code&gt;Dot&lt;/code&gt; custom type that better fits the domain of the problem and did small updates in the &lt;code&gt;generateDot&lt;/code&gt; function and in the type annotation of the &lt;code&gt;generateDotsFromMatrix&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The last change is at our &lt;code&gt;renderDice&lt;/code&gt; function, we'll change every occurrence of &lt;code&gt;True&lt;/code&gt; to &lt;code&gt;Dot&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; to &lt;code&gt;Placeholder&lt;/code&gt; that way we can easily understand if some of the faces have something weird going on later.&lt;/p&gt;

&lt;p&gt;That's a small change but with a big impact on how we handle our code since using this custom type helps on understand what is being rendered for each part of the face representation and catch any weird logic change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Easy, the matrix that corresponds to 2.&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Dot&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Placeholder&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Dot&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;I know that everyone who's worked with Elm at a higher degree than pet projects will say that custom type should be considered and implemented from the start but I'm showing how my thought process was during this small challenge which had a specific time to finish while also trying to keep it easy to digest for people who are not really used to code with the language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ellie-app.com/gYMvyFk84pna1" rel="noopener noreferrer"&gt;Here's the Full App&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Considerations &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The group of people whose interviewed me was really thoughtful and easy going. They not only gave me the whole boilerplate to start with but also let me consult the documentation and even &lt;em&gt;Stack Overflow&lt;/em&gt; if I wanted to. That's something that most technical interviews, at least that I've been through, tend to prevent you from doing. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;But isn't that what we do, daily, as programmers?&lt;/em&gt; Check documentation, search for syntax specifics and sometimes understand how to do something through the experience of others. It should not be taken away just to see if you can hold a bunch of information that can be easily searched throughout internet. Our job should be based on problem solving not to try and hold a ginormous amount of information in our heads.&lt;/p&gt;

&lt;p&gt;Throughout the interview the whole group was also really supportive and interactive, helping me not wander so much with the implementation details so I wouldn't throw curve balls to handle later. That's also something that a number of technical interviewers tend not to do. They see themselves as spectators, not interviewers. Pretend that they can't help you because if they do its like "cheating" but that's not the case and it's really good to see that whoever is interviewing you isn't just a static judge but a fellow developer who's capable of discuss and help you to build a better mindset for the problem while also preventing you to go down some unnecessary rabbit holes. That's what's expected from a good pair programming and what I think most interviewees want from a technical interview. &lt;em&gt;They also want to be hired but that's a whole different conversation...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My final consideration is that you don't need complex problems to access someone's expertise and if you're an interviewer, you don't need to be a static judge. Strive to be someone that answer questions, pair programming and help the interviewee to feel heard and ease their concerns. I bet you can learn a bunch from them and vice-versa. Just be a fellow developer and enjoy the possibility to get to know a bunch of other developers with different backgrounds and experiences.&lt;/p&gt;




&lt;h2&gt;
  
  
  TLDR &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A pretty simple but funny technical interview challenge with minor details that enable the interviewers to grasp the experience level of the interviewee with the language.&lt;br&gt;
&lt;a href="https://ellie-app.com/gYMvyFk84pna1" rel="noopener noreferrer"&gt;Full implementation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>elm</category>
      <category>functional</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Tagged Union in React.Js with TypeScript and how to respect your props.</title>
      <dc:creator>Zenobio</dc:creator>
      <pubDate>Fri, 23 Apr 2021 18:48:38 +0000</pubDate>
      <link>https://dev.to/zenobio/tagged-union-in-typescript-react-js-and-how-to-respect-your-props-58j1</link>
      <guid>https://dev.to/zenobio/tagged-union-in-typescript-react-js-and-how-to-respect-your-props-58j1</guid>
      <description>&lt;p&gt;If you've ever used languages like Elm or ReasonML for writing any front-end application then you are probably familiar with the terms Tagged Union, Variants or even Discriminated Unions, but if it is not the case, let me show what i'm referring to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Full code example at: https://ellie-app.com/cYzXCP7WnNDa1&lt;/span&gt;

&lt;span class="c1"&gt;-- FieldType is a Tagged union.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;FieldType&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Editable&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;ViewOnly&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;initial&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ViewOnly&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to ELM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;succeed&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perform&lt;/span&gt; &lt;span class="kt"&gt;Init&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Init&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;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;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kt"&gt;Handle&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;-&amp;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;model&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Model&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt;
&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;kind&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="kt"&gt;Editable&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;
              &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;onInput&lt;/span&gt; &lt;span class="kt"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
            &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Value: "&lt;/span&gt; &lt;span class="o"&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="kt"&gt;ViewOnly&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;  &lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above displays one of Elm's main strengths when we talk about modeling your application based on data types.&lt;/p&gt;

&lt;p&gt;Don't be afraid of all the boilerplate, the main point here is how we have a completely agnostic &lt;code&gt;view&lt;/code&gt; while also being 100% sure that our model can't and won't be in a undetermined state or have any missing props, never.&lt;/p&gt;

&lt;p&gt;Our model property &lt;code&gt;kind&lt;/code&gt; will never contain anything different from a &lt;code&gt;FieldType&lt;/code&gt; and with the help of the Elm compiler we could rest assure that our view will also be reliable and always have all the needed data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typescript
&lt;/h2&gt;

&lt;p&gt;Today, Typescript have been massively used as a tool which helps in minimize some runtime errors and give some guarantees about what exactly are our Data inside the sea of uncertainty that is Javascript code.&lt;/p&gt;

&lt;p&gt;That being said, let's take a look on how commonly components are validated in some React with Typescript code bases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// FieldType could also be just the strings values.&lt;/span&gt;
&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;FieldType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;VIEW_ONLY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewOnly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;EDITABLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VFC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="c1"&gt;// ...component implementation&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler will prevent you from use the component without the required props, but, do you really need a &lt;code&gt;onChange&lt;/code&gt; function if you just want a non editable field?&lt;/p&gt;

&lt;p&gt;What about any new member which enters the team, how will this component plays when someone with no deep understanding of every and each component in the code base tries to use it somewhere else?&lt;/p&gt;

&lt;p&gt;Sure, the code above just shows a simple &lt;code&gt;Field&lt;/code&gt; component, nothing that we couldn't reason about just reading the code, but, it is far from a good implementation if you do want to respect the props, the component behavior for each kind of implementation and how it will play when it is needed somewhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tagged Unions for the rescue.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Talk is cheap, show me the code", Linus Torvalds&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;FieldType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;VIEW_ONLY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewOnly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;EDITABLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;BaseProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Editable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EDITABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChangeEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseProps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ViewOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VIEWONLY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;BaseProps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ViewOnly&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Editable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VFC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kind&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Editable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// ...component implementation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we have some extra &lt;em&gt;type boilerplate&lt;/em&gt; but our component props would be respected and enforced by a known &lt;code&gt;FieldType&lt;/code&gt; just like we intended to when the component was implemented. Now, what if we try to call our component without any property? what will happen?&lt;/p&gt;

&lt;p&gt;Well, at first, Typescript will show you an error in compile time;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;assignable&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;(IntrinsicAttributes &amp;amp; { kind: FieldType.VIEW_ONLY; } &amp;amp; DefaultProps) | (IntrinsicAttributes &amp;amp; { kind: FieldType.EDITABLE; onChange: (_: ChangeEvent&amp;lt;...&amp;gt;) =&amp;gt; void; } &amp;amp; DefaultProps)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;missing&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{ kind: FieldType.EDITABLE; onChange: (_: ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; void; }&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then,after you provide the property &lt;code&gt;kind&lt;/code&gt; with a known &lt;code&gt;FieldType&lt;/code&gt;, it will show you which properties you still need to provide to ensure that your component has everything it needs to work as expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;Property&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;onChange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;missing&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{ kind: FieldType.EDITABLE; }&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;but&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{ kind: FieldType.EDITABLE; onChange: (_: ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; void; }&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you just need to use a mapped object or a switch case in your &lt;code&gt;Field component&lt;/code&gt; render, which, based on the enforced prop &lt;code&gt;kind&lt;/code&gt; and given your nullable or not nullable props enforced by the tagged union, it'll show you exactly what needs and not needs to be handled, formatted or treated.&lt;/p&gt;

&lt;p&gt;For the sake of reusability the &lt;code&gt;FieldType&lt;/code&gt; enum can be moved to a &lt;code&gt;types/field&lt;/code&gt; or a &lt;code&gt;types/components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's an implementation for example pourposes:&lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/discriminatedunioncomponent-xmb47"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;IMHO that's one of the best ways to really use the Typescript compiler to help us compose code. &lt;/p&gt;

&lt;p&gt;Not only validating our components within nullable or non nullable &lt;code&gt;props&lt;/code&gt; values, but also helping in the proper implementation while also being thoughtful of the ones who will come to use, maintain and update the code base.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>functional</category>
      <category>typescript</category>
    </item>
    <item>
      <title>JS Sort is "weird".</title>
      <dc:creator>Zenobio</dc:creator>
      <pubDate>Wed, 24 Mar 2021 05:51:54 +0000</pubDate>
      <link>https://dev.to/zenobio/js-sort-is-weird-22e2</link>
      <guid>https://dev.to/zenobio/js-sort-is-weird-22e2</guid>
      <description>&lt;p&gt;It does not take a highly experienced JS programmer to notice that &lt;code&gt;Array.prototype.sort&lt;/code&gt; works in his own "weird" way. But maybe you're not familiar with JS at all, in that case, let me show you what i mean by "weird":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;span class="c1"&gt;// Result: (5) [101, 1025, 2, 32, 43, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  TL:DR
&lt;/h2&gt;

&lt;p&gt;The sort method turns each and every value into string and then compare their sequences of UTF-16 code units values, leading to the "weird" behavior. &lt;/p&gt;

&lt;h2&gt;
  
  
  Not so brief explanation:
&lt;/h2&gt;

&lt;p&gt;Going into &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort" rel="noopener noreferrer"&gt;MDN docs&lt;/a&gt; we are given the following information:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;sort()&lt;/code&gt; method sorts the elements of an array in place  and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we know that the value is really compared as a string in UTF-16, lets check the values for our first test in this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;charCodeAt0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="cm"&gt;/* Result: [{…}, {…}, {…}, {…}, {…}, {…}]
0: {value: 32, unityCharCode: 51}
1: {value: 2, unityCharCode: 50}
2: {value: 43, unityCharCode: 52}
3: {value: 101, unityCharCode: 49}
4: {value: 1025, unityCharCode: 49}
5: {value: 5, unityCharCode: 53}
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's nice, if you check some &lt;a href="https://stackoverflow.com/questions/234683/javascript-array-sort-implementation" rel="noopener noreferrer"&gt;stackoverflow questions&lt;/a&gt; about how sort is implemented inside the JS motor, isn't hard to see that it's a simple &lt;a href="https://en.cppreference.com/w/cpp/algorithm/qsort" rel="noopener noreferrer"&gt;std::qsort&lt;/a&gt; from C++ which will sort the given values alphabetically ascending if no &lt;code&gt;comparison function&lt;/code&gt; is provided.&lt;/p&gt;

&lt;p&gt;So if we provide a function which compare the &lt;code&gt;charCodeAt0&lt;/code&gt; property for our generated object, we should end with a list sorted the same way, right? Let's test it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;unityCharCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unityCharCode&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;unityCharCode&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cm"&gt;/* Result: [{…}, {…}, {…}, {…}, {…}, {…}]
0: {value: 101, unityCharCode: 49}
1: {value: 1025, unityCharCode: 49}
2: {value: 2, unityCharCode: 50}
3: {value: 32, unityCharCode: 51}
4: {value: 43, unityCharCode: 52}
5: {value: 5, unityCharCode: 53}
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, is seems just like the first test.&lt;/p&gt;

&lt;h2&gt;
  
  
  But, which function should i use?
&lt;/h2&gt;

&lt;p&gt;Having a little more understanding of how the &lt;code&gt;Array.prototype.sort&lt;/code&gt; runs, we can pass a &lt;code&gt;comparison function&lt;/code&gt; to handle the sort in the way we want it to:&lt;/p&gt;

&lt;p&gt;Alphabetically ascending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only Numbers:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Result: [2, 5, 32, 43, 101, 1025]&lt;/span&gt;

&lt;span class="c1"&gt;// Only Letters:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;j&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Result: ["A", "D", "a", "c", "d", "e", "j", "k"]&lt;/span&gt;

&lt;span class="c1"&gt;// Letters and Numbers:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;j&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Result: ["A", "a", "b", "c", "j", 5, 32, 43, 1025]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alphabetically descending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only Numbers:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Result: [1025, 101, 43, 32, 5, 2]&lt;/span&gt;

&lt;span class="c1"&gt;// Only Letters:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;j&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;k&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Result: ["k", "j", "e", "d", "c", "a", "D", "A"]&lt;/span&gt;

&lt;span class="c1"&gt;// Letters and Numbers:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;j&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Result: ["j", "c", "b", "a", "A", 1025, 43, 32, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case you want to take it a step further and use a custom function that could validate any of the above cases for you, there you go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compareNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compareWords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;asc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}[&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compareFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&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;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&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="nf"&gt;compareNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&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="nf"&gt;compareWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&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="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;j&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;compareFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Result: ["A", "a", "b", "c", "j", 5, 32, 43, 1025]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What about undefined?
&lt;/h2&gt;

&lt;p&gt;Well, &lt;code&gt;undefined&lt;/code&gt; is a edge case for sort, it will always have a bigger comparison value than any other, so it will always shown in the end of a sorted list.&lt;/p&gt;

&lt;p&gt;It doesn't get more complex than this (no pun intended).&lt;br&gt;
You can also check the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare" rel="noopener noreferrer"&gt;String.prototype.localeCompare&lt;/a&gt; which is pretty good for sorting some words or letters considering that it can differentiate between upper or lower case and also accents.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>sort</category>
    </item>
  </channel>
</rss>
