<?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: Douglas Modena</title>
    <description>The latest articles on DEV Community by Douglas Modena (@dmodena).</description>
    <link>https://dev.to/dmodena</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%2F511294%2F8147b40d-a8b8-4b12-94b2-ca3a85a08125.jpeg</url>
      <title>DEV Community: Douglas Modena</title>
      <link>https://dev.to/dmodena</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmodena"/>
    <language>en</language>
    <item>
      <title>JavaScript beyond Simple Functions</title>
      <dc:creator>Douglas Modena</dc:creator>
      <pubDate>Thu, 08 Feb 2024 21:34:12 +0000</pubDate>
      <link>https://dev.to/dmodena/javascript-beyond-simple-functions-15m7</link>
      <guid>https://dev.to/dmodena/javascript-beyond-simple-functions-15m7</guid>
      <description>&lt;p&gt;Wether you are new to programming or not, functions are at the core of many programming languages, especially JavaScript. Simple functions encapsulate logic, execute actions according to parameters and allow for returning some result or not. But JavaScript enables you to expand the trivial use of functions with some features.&lt;/p&gt;

&lt;p&gt;In this article we will explore how to go beyond the use of simple functions, understanding the concept and usage of higher order functions, closures and generators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple Functions
&lt;/h2&gt;

&lt;p&gt;A function is a "set of statements that perform a task or calculates a value"¹. We can see below an example of a function in JavaScript:&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;function&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numberA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numberB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numberC&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="nx"&gt;numberA&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;numberB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;numberC&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 function receives three parameters: &lt;code&gt;numberA&lt;/code&gt;, &lt;code&gt;numberB&lt;/code&gt; and &lt;code&gt;numberC&lt;/code&gt;. It multiplies them and returns the result. This is the standard syntax for creating functions in JavaScript, but we could also write using the Arrow function syntax:&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;multiply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numberA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numberB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numberC&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;numberA&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;numberB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;numberC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrow functions provide a cleaner syntax, which in some cases may improve readability. Just keep in mind that this syntax has some limitations².&lt;/p&gt;

&lt;h3&gt;
  
  
  Pure Functions and Side Effects
&lt;/h3&gt;

&lt;p&gt;You may have already heard the term "Pure Function", but what is that exactly?&lt;/p&gt;

&lt;p&gt;Due to the flexibility that functions provide, nothing would prevent us from creating the following function:&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;let&lt;/span&gt; &lt;span class="nx"&gt;someValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum&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;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;someValue&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="k"&gt;return&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;b&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;By looking at the function name, you would expect it to return the sum of &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, but it is also changing a value from a variable that was not passed as parameter. We refer to this as a &lt;strong&gt;side effect&lt;/strong&gt; of the function.&lt;/p&gt;

&lt;p&gt;In order to be considered pure³, a function must comply with the following rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Given the same inputs, the function must always return the same output;&lt;/li&gt;
&lt;li&gt;The function must not have any side effects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We've already seen an example of a pure function, the one used to multiply three values. That function does not act on anything outside of it's scope and always returns the same values for the same input (for example, given the values 1, 2, and 3, it will always return 6).&lt;/p&gt;

&lt;p&gt;It is easier to reason about and debug pure functions, but sometimes we actually want to have impure functions, such as one that returns a different value every time it is called, as we will see later in the article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Higher order functions
&lt;/h2&gt;

&lt;p&gt;Functions may receive different types of parameters. In the examples we've seen so far, we are always passing numbers as parameters. But functions can receive several other types, such as strings, arrays, booleans, objects and even &lt;strong&gt;functions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You read that right: you can pass a function as a parameter to another function. Let's see how that is done:&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;function&lt;/span&gt; &lt;span class="nf"&gt;add2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&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="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;subtract2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&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="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculate&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;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&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;b&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;fn&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="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;add2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 9&lt;/span&gt;
&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subtract2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;add2&lt;/code&gt; function simply adds 2 to any number it receives, while the &lt;code&gt;subtract2&lt;/code&gt; subtracts 2 from its parameter.&lt;/p&gt;

&lt;p&gt;The calculate function does 2 things: first it sums the values of &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;. Then the result of this sum (&lt;code&gt;c&lt;/code&gt;) is passed to the function it receives as &lt;code&gt;fn&lt;/code&gt;, to be returned at the end. This provides the flexibility of performing different types of calculations according to the provided function.&lt;/p&gt;

&lt;p&gt;After the function definitions we execute &lt;code&gt;calculate&lt;/code&gt; twice, with the same numbers: 3 and 4. The first time we are passing the &lt;code&gt;add2&lt;/code&gt; function as parameter, and the result is &lt;code&gt;3 + 4 = 7 =&amp;gt; 7 + 2 = 9&lt;/code&gt;, therefore it returns &lt;code&gt;9&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second time we pass the &lt;code&gt;subtract2&lt;/code&gt; function as parameter, and the result is &lt;code&gt;3 + 4 = 7 =&amp;gt; 7 - 2 = 5&lt;/code&gt;, therefore it returns &lt;code&gt;5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A function that receives another function as parameter is called a &lt;strong&gt;Higher Order Function&lt;/strong&gt;⁴, and it is a very useful feature of JavaScript. One popular higher order function in JavaScript is the &lt;code&gt;sort()&lt;/code&gt; function.&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;users&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="na"&gt;id&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="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&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="na"&gt;id&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="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mark Johnson&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jack Smith&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mary Doe&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="na"&gt;id&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="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Abigail David&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Stuart Fox&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compareByAge&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;b&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="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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;return&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compareByLastName&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;b&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;lastNameA&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;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&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="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastNameB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;b&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&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="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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;lastNameA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastNameB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;users&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;b&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;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// users ordered by descending id&lt;/span&gt;
&lt;span class="nx"&gt;users&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;compareByAge&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// users ordered by age &lt;/span&gt;
&lt;span class="nx"&gt;users&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;compareByLastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// users ordered by last name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Array.prototype.sort()&lt;/code&gt; function is a higher order function that can have a comparer function passed as parameter⁵. It can sort an array in different ways, depending on the function it receives. In our example, the first time we called &lt;code&gt;sort()&lt;/code&gt; we passed a simple arrow function to sort the items by id in descending order. The second time we passed a function that compares the ages, and sorts by age in ascending order. The third time we compared last names, using the built-in string function &lt;code&gt;localCompare()&lt;/code&gt;⁶.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closures
&lt;/h2&gt;

&lt;p&gt;Functions have scopes for accessing variables. In one of our examples, we were able to change a value that was defined outside of our function. Closures follow the same idea, which means that it provides access to variables within its scope.&lt;/p&gt;

&lt;p&gt;According to MDN, a closure is "the combination of a function and the lexical environment within which that function was declared"⁷. Let's see how we could make use of a Closure with an example.&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;function&lt;/span&gt; &lt;span class="nf"&gt;sumAllMaker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sumAll&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;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;total&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="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;total&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="nx"&gt;sumAll&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;totalSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sumAllMaker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;totalSum&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="nf"&gt;totalSum&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="nf"&gt;totalSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&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="c1"&gt;// 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand what is going on with our example, let's start by looking at the inner function, called &lt;code&gt;sumAll()&lt;/code&gt;. This function receives 2 parameters, and sums them. The result is then aggregated to &lt;code&gt;total&lt;/code&gt;, which is a variable outside of &lt;code&gt;sumAll()&lt;/code&gt;. The variable was declared in the outer function, but just like we could previously access global variables, here we have access to variables in the outer function. So, subsequent calls to this function will always update the value stored in total.&lt;/p&gt;

&lt;p&gt;Now let's look at the outer function: &lt;code&gt;sumAllMaker()&lt;/code&gt;. It's starts by assigning 0 to our variable &lt;code&gt;total&lt;/code&gt;. Then it defines the function &lt;code&gt;sumAll()&lt;/code&gt; which is where the logic to update the total resides, and at the end it returns a reference to the function &lt;code&gt;sumAll&lt;/code&gt;. That is important because now we can declare a variable, and by assigning &lt;code&gt;sumAllMaker()&lt;/code&gt; to it we get access to the &lt;code&gt;sumAll&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;In other words, now that we declared &lt;code&gt;const totalSum = sumAllMaker()&lt;/code&gt;, calling &lt;code&gt;totalSum()&lt;/code&gt; is the same as calling the &lt;code&gt;sumAll()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Finally we call the function 3 times. Notice that the first time we call it with the values 1 and 2, it returns 3. The second time we call it with the same values, it returns 6. That is because the total is being kept and updated every time we call the function.&lt;/p&gt;

&lt;p&gt;That is our closure in action! We called it once more, and it returned 10. Any subsequent calls will continue to update total and return it appropriately. Notice that this closure cannot be considered a pure function, because calling the same function twice with the same parameters return different results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generator Functions
&lt;/h2&gt;

&lt;p&gt;Imagine that you are creating objects and you want each of them to have a different id. You don't want to manually assign ids, instead you would like to create a function to generate them.&lt;/p&gt;

&lt;p&gt;One way to solve it would be to create a random⁸ number generator.&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;function&lt;/span&gt; &lt;span class="nf"&gt;getRandomInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&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="nx"&gt;max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;getRandomInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 926&lt;/span&gt;
&lt;span class="nf"&gt;getRandomInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 508&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just as an exercise, would you be able to explain wether &lt;code&gt;getRandomInteger()&lt;/code&gt; is a pure function, and why?&lt;/p&gt;

&lt;p&gt;Using this function would not work for our scenario because nothing guarantees that the function would return unique numbers. At some point I could get the same id again, since it's random, there is no control on which number is returned.&lt;/p&gt;

&lt;p&gt;As we've seen previously, we could use a closure to solve that.&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;function&lt;/span&gt; &lt;span class="nf"&gt;idMaker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getId&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="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;id&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;idMaker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 101&lt;/span&gt;
&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 102&lt;/span&gt;
&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 103&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's awesome! Now we know how to use a closure to generate ids. But there is another way to achieve this, by using a generator.&lt;/p&gt;

&lt;p&gt;A generator function uses a special notation, including an asterisk after the function keyword: &lt;code&gt;function*&lt;/code&gt;⁹. This type of function returns an object that can be iterated upon. Think of it as a function that can be paused and resumed. Within the function, the &lt;code&gt;yield&lt;/code&gt; statement is what "pauses" the function, returning some value. Subsequent calls to the generator will resume from the last &lt;code&gt;yield&lt;/code&gt; until the next one, and so on.&lt;/p&gt;

&lt;p&gt;Let's see an example using a simple generator that returns the vowels.&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;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;generateVowels&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="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="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;e&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;u&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vowels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateVowels&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;vowels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 'a'&lt;/span&gt;
&lt;span class="nx"&gt;vowels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 'e'&lt;/span&gt;
&lt;span class="nx"&gt;vowels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 'i'&lt;/span&gt;
&lt;span class="nx"&gt;vowels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 'o'&lt;/span&gt;
&lt;span class="nx"&gt;vowels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 'u'&lt;/span&gt;
&lt;span class="nx"&gt;vowels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, every time we call the &lt;code&gt;next()&lt;/code&gt; function and get the value, a subsequent &lt;code&gt;yield&lt;/code&gt; is executed, until the iterator completes. After that, any further execution returns &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Considering what we've seen so far, would you be able to create a generator that returns ids from 101 until 999? If you feel like it, pause reading and go try it for yourself! Otherwise, the answer follows below.&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;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;generateIds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;id&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateIds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 101&lt;/span&gt;
&lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 102&lt;/span&gt;
&lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 103&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;JavaScript is a powerful language, and it provides flexible ways of working with functions. Try to find opportunities in your routine to integrate some of these options, and go beyond the use of simple functions.&lt;/p&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions"&gt;Functions - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions"&gt;Arrow function expressions - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/what-is-a-pure-function-in-javascript-acb887375dfe/"&gt;What is a Pure Function in JavaScript - freeCodeCamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/higher-order-functions-in-javascript-explained/"&gt;Higher Order Functions in JavaScript – Explained with Practical Examples - freeCodeCamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;Array.prototype.sort() - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare"&gt;String.prototype.localeCompare() - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;Closures - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random"&gt;Math.random() - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*"&gt;function* - MDN web docs&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Difference between JOIN and WHERE clauses in SQL</title>
      <dc:creator>Douglas Modena</dc:creator>
      <pubDate>Thu, 24 Aug 2023 00:00:40 +0000</pubDate>
      <link>https://dev.to/dmodena/difference-between-join-and-where-clauses-in-sql-41pi</link>
      <guid>https://dev.to/dmodena/difference-between-join-and-where-clauses-in-sql-41pi</guid>
      <description>&lt;p&gt;In SQL, JOIN is used to link two or more tables together in a single result set, and the WHERE clause is used to filter the results based on some criteria. That seems simple, but do we really understand how they affect our queries?&lt;/p&gt;

&lt;p&gt;In order to take a deeper look at it, we'll create a simple database as an example. And the best example I can think of now is pizza! 🍕&lt;/p&gt;

&lt;h2&gt;
  
  
  The database structure
&lt;/h2&gt;

&lt;p&gt;Our Pizza Shop database has 2 main tables: customers and pizzas. The only other table is orders, which connects the other two.&lt;/p&gt;

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

&lt;p&gt;The contents of the three tables follow below. If you'd like, you can create the same database on your end, and verify that you get the same results.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

customers        pizzas                          orders
==============   =============================   ===================================
id | name        id | flavor           | price   date       | customer_id | pizza_id
-- | ---------   -- | ---------------- | -----   ---------- | ----------- | --------
1  | Beatrice    1  | Americana        | 7.10    2023-03-08 | 6           | 6
2  | Enrico      2  | Caprese          | 7.00    2023-03-15 | 3           | 7
3  | Francesco   3  | Funghi           | 7.80    2023-03-22 | 1           | 4
4  | Giovanni    4  | Margherita       | 5.70    2023-04-12 | 2           | 4
5  | Giuseppe    5  | Napoletana       | 5.80    2023-04-21 | 2           | 7
6  | Maria       6  | Nutella          | 6.90    2023-05-08 | 7           | 1
7  | Nina        7  | Prosciutto       | 7.90    2023-05-09 | 2           | 4
                 8  | Quattro Formaggi | 7.00    2023-05-15 | 3           | 4
                 9  | Tonno            | 7.70    2023-06-03 | 1           | 9
                 10 | Verdure          | 7.00    2023-06-10 | 2           | 8
                                                 2023-06-14 | 7           | 6
                                                 2023-06-22 | 7           | 8
                                                 2023-06-26 | 3           | 10


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Filtering results with WHERE
&lt;/h2&gt;

&lt;p&gt;Let's start with the simpler, and dare I say, one of the most common keywords in SQL: WHERE.&lt;/p&gt;

&lt;p&gt;You could select all Customers with a simple query:&lt;br&gt;&lt;br&gt;
&lt;code&gt;SELECT * FROM shop.customers&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name
-- | ---------
1  | Beatrice
2  | Enrico
3  | Francesco
4  | Giovanni
5  | Giuseppe
6  | Maria
7  | Nina


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

&lt;/div&gt;

&lt;p&gt;But if you only want to see the customers starting with the letter G, you could add this condition and filter the results:&lt;br&gt;&lt;br&gt;
&lt;code&gt;SELECT * FROM shop.customers WHERE name LIKE 'G%'&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name
-- | --------
4  | Giovanni
5  | Giuseppe


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

&lt;/div&gt;

&lt;p&gt;You can have all kinds of conditions in a WHERE clause, for example comparing strings (like we did for the name), dates (&lt;code&gt;WHERE birthday &amp;gt; '1989-01-01'&lt;/code&gt;), boolean (&lt;code&gt;WHERE is_premium IS FALSE&lt;/code&gt;), number (&lt;code&gt;WHERE price &amp;lt; 5.50&lt;/code&gt;), and these are just a few examples.&lt;/p&gt;

&lt;p&gt;The WHERE clause can be used not only with SELECT statements. Actually you must use it with DELETE statements - unless your intent is to wipe out all the data from a table, but even then, you're better off using TRUNCATE instead of DELETE. So, don't forget to use WHERE in your DELETE statements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linking tables with JOIN
&lt;/h2&gt;

&lt;p&gt;There are several types of JOINs, but let's look at the most common ones: INNER JOIN, LEFT JOIN and RIGHT JOIN.&lt;/p&gt;

&lt;p&gt;Let's represent our tables with circles. Circle A represents our customers, B represents our pizzas, and the intersection represents customers who actually bought pizzas, from our orders.&lt;/p&gt;

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

&lt;p&gt;To view all values from A, we simply select from our customers table:&lt;br&gt;&lt;br&gt;
&lt;code&gt;SELECT * FROM shop.customers&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Similarly, we can retrieve B by selecting from pizzas:&lt;br&gt;&lt;br&gt;
&lt;code&gt;SELECT * FROM shop.pizzas&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Now to the JOINs.&lt;/p&gt;

&lt;h3&gt;
  
  
  INNER JOIN
&lt;/h3&gt;

&lt;p&gt;If I want to see all customers who ordered pizzas, I could do so using an INNER JOIN. Notice: if I only use JOIN in my query, INNER JOIN is implied.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT DISTINCT c.id, c."name"
FROM shop.customers c
JOIN shop.orders o ON c.id = o.customer_id
ORDER BY c."name"


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

&lt;/div&gt;

&lt;p&gt;Similarly I could view all pizzas that were ever ordered:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT DISTINCT p.id, p.flavor, p.price
FROM shop.pizzas p
JOIN shop.orders o ON p.id = o.pizza_id
ORDER BY p.flavor


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

&lt;/div&gt;

&lt;p&gt;These 2 can be represented by the intersection between the circles.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  LEFT JOIN
&lt;/h3&gt;

&lt;p&gt;To view how many pizzas each customer ordered, I could COUNT the number of orders for each customer:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT c.id, c."name", COUNT(o.customer_id) AS pizzas_ordered
FROM shop.customers c
JOIN shop.orders o ON c.id = o.customer_id
GROUP BY c.id, c."name"
ORDER BY c."name"


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

&lt;/div&gt;

&lt;p&gt;Running this query returns the following result:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name      | pizzas_ordered
-- | --------- | --------------
1  | Beatrice  | 2
2  | Enrico    | 4
3  | Francesco | 3
6  | Maria     | 1
7  | Nina      | 3


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

&lt;/div&gt;

&lt;p&gt;As you can see, only 5 rows were returned, but we know we have 7 customers. What happened? Well, the other 2 customers have not ordered any pizzas yet, and since we're using INNER JOIN in our query, they are not returned.&lt;/p&gt;

&lt;p&gt;If we want to see all customers, including those who haven't ordered yet, we just have to replace the INNER JOIN in our query with LEFT JOIN:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT c.id, c."name", COUNT(o.customer_id) AS pizzas_ordered
FROM shop.customers c LEFT JOIN shop.orders o ON c.id = o.customer_id
GROUP BY c.id, c."name"
ORDER BY c."name"


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

&lt;/div&gt;

&lt;p&gt;LEFT JOIN returns all rows from the table on the LEFT, even if they don't match any records on the table from the right. I left the two tables on the same line of the query to better show which table is on the left of the JOIN and which is on the right.&lt;/p&gt;

&lt;p&gt;We can represent the results with the A and B circles, resulting with the full set of A, including the intersection between A and B.&lt;/p&gt;

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

&lt;p&gt;Now we get the results we were expecting:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name      | pizzas_ordered
-- | --------- | --------------
1  | Beatrice  | 2
2  | Enrico    | 4
3  | Francesco | 3
4  | Giovanni  | 0
5  | Giuseppe  | 0
6  | Maria     | 1
7  | Nina      | 3


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  RIGHT JOIN
&lt;/h3&gt;

&lt;p&gt;Works just like the LEFT JOIN, but brings all records from the table on the RIGHT, even if they don't match any records on the table from the LEFT. We could rewrite the same query to use RIGHT JOIN by just changing positions:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT c.id, c."name", COUNT(o.customer_id) AS pizzas_ordered
FROM shop.orders o RIGHT JOIN shop.customers c ON o.customer_id = c.id
GROUP BY c.id, c."name"
ORDER BY c."name"


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name      | pizzas_ordered
-- | --------- | --------------
1  | Beatrice  | 2
2  | Enrico    | 4
3  | Francesco | 3
4  | Giovanni  | 0
5  | Giuseppe  | 0
6  | Maria     | 1
7  | Nina      | 3


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

&lt;/div&gt;

&lt;p&gt;Just like the LEFT JOIN, this can be represented with the A and B circles, this time with the full set of B, and the intersection between A and B.&lt;/p&gt;

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

&lt;p&gt;Let's see another example. The following query will return how many pizzas of each flavor were sold, including the flavors that were not sold at all:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT p.id, p.flavor, COUNT(o.pizza_id) AS pizzas_ordered
FROM shop.orders o
RIGHT JOIN shop.pizzas p ON o.pizza_id = p.id
GROUP BY p.id, p.flavor
ORDER BY p.flavor


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | flavor           | pizzas_ordered
-- | ---------------- | --------------
1  | Americana        | 1
2  | Caprese          | 0
3  | Funghi           | 0
4  | Margherita       | 4
5  | Napoletana       | 0
6  | Nutella          | 2
7  | Prosciutto       | 2
8  | Quattro Formaggi | 2
9  | Tonno            | 1
10 | Verdure          | 1


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

&lt;/div&gt;

&lt;p&gt;The result shows that Margherita was the most ordered flavor, while Caprese, Funghi and Napoletana were not ordered at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Combining JOIN and WHERE
&lt;/h2&gt;

&lt;p&gt;This is where it could get tricky. If we're not attentive, we could end up writing redundant queries or even wrong queries according to the result we're expecting.&lt;/p&gt;

&lt;p&gt;Let's say we're trying to retrieve the customers who bought pizzas, ordering by the amount of pizzas per customer.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT c.id, c."name", COUNT(o.customer_id) AS pizzas_ordered
FROM shop.customers c
JOIN shop.orders o ON c.id = o.customer_id
GROUP BY c.id, c."name"
HAVING COUNT(o.customer_id) &amp;gt; 0
ORDER BY COUNT(o.customer_id)


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name      | pizzas_ordered
-- | --------- | --------------
6  | Maria     | 1
1  | Beatrice  | 2
3  | Francesco | 3
7  | Nina      | 3
2  | Enrico    | 4


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

&lt;/div&gt;

&lt;p&gt;In this query we are using the keyword HAVING instead of WHERE since we're dealing with an aggregate function. You can think of HAVING as the WHERE clause used for columns that use functions such as COUNT, SUM, etc.&lt;/p&gt;

&lt;p&gt;The query above brings the correct results, but we don't actually need the HAVING there. Why not? Well, we're already using a JOIN (INNER JOIN), which only returns results when there is a match between the 2 tables, hence no customers without orders will ever be returned. That's why the HAVING clause is redundant, and can be removed.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT c.id, c."name", COUNT(o.customer_id) AS pizzas_ordered
FROM shop.customers c
JOIN shop.orders o ON c.id = o.customer_id
GROUP BY c.id, c."name"
ORDER BY COUNT(o.customer_id)


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

&lt;/div&gt;

&lt;p&gt;This query is shorter and returns the exact same result.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | name      | pizzas_ordered
-- | --------- | --------------
6  | Maria     | 1
1  | Beatrice  | 2
3  | Francesco | 3
7  | Nina      | 3
2  | Enrico    | 4


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

&lt;/div&gt;

&lt;p&gt;Now let's say we're creating a report and we want to see how much money we made from the orders of each flavor of pizza during the month of May.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT p.id, p.flavor, COUNT(o.pizza_id) * p.price AS total
FROM shop.pizzas p
JOIN shop.orders o ON p.id = o.pizza_id
WHERE o."date" BETWEEN '2023-05-01' AND '2023-05-31'
GROUP BY p.id, p.flavor
ORDER BY p.flavor


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | flavor     | total
-- | ---------- | -----
1  | Americana  |  7.10
4  | Margherita | 11.40


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

&lt;/div&gt;

&lt;p&gt;We can see from the result that during May we made 7.10 by selling Americana pizzas and 11.40 from Margherita pizzas. But how about the other flavors?&lt;/p&gt;

&lt;p&gt;Well, we're using INNER JOIN in our query, so we're not bringing all flavors of pizza. Let's replace that with LEFT JOIN.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT p.id, p.flavor, COUNT(o.pizza_id) * p.price AS total
FROM shop.pizzas p
LEFT JOIN shop.orders o ON p.id = o.pizza_id
WHERE o."date" BETWEEN '2023-05-01' AND '2023-05-31'
GROUP BY p.id, p.flavor
ORDER BY p.flavor


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | flavor     | total
-- | ---------- | -----
1  | Americana  |  7.10
4  | Margherita | 11.40


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

&lt;/div&gt;

&lt;p&gt;We changed our JOIN, but still got the same result. Why was that? This is the reason for writing this article, understanding how our JOINs and WHERE clauses affect our result.&lt;/p&gt;

&lt;p&gt;In our query we used LEFT JOIN, so we should be getting all pizzas, including those that were not sold. Considering circle A as our customers table, B as pizzas and the intersection as the orders. We should be getting something like this:&lt;/p&gt;

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

&lt;p&gt;And we are indeed getting it, we could verify that by removing the WHERE clause:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT p.id, p.flavor, COUNT(o.pizza_id) * p.price AS total
FROM shop.pizzas p
LEFT JOIN shop.orders o ON p.id = o.pizza_id
GROUP BY p.id, p.flavor
ORDER BY p.flavor


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | flavor           | total
-- | ---------------- | -----
1  | Americana        |  7.10
2  | Caprese          |  0.00
3  | Funghi           |  0.00
4  | Margherita       | 22.80
5  | Napoletana       |  0.00
6  | Nutella          | 13.80
7  | Prosciutto       | 15.80
8  | Quattro Formaggi | 14.00
9  | Tonno            |  7.70
10 | Verdure          |  7.00


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

&lt;/div&gt;

&lt;p&gt;We saw that we're retrieving all the pizzas, but our WHERE clause is filtering out the results, and this is exactly the purpose of the WHERE clause.&lt;/p&gt;

&lt;p&gt;Keep this in mind: in order to bring the correct results, we need to understand how to link our tables with the correct JOIN (if we should use LEFT, RIGHT, INNER, or other types of JOINs), and after that, how we're filtering the results with our WHERE clause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution to this problem
&lt;/h2&gt;

&lt;p&gt;Whenever we face a situation in which we believe the query is not returning the expected result, my tip is to remove the WHERE clauses, and review the JOINs. Check to see if you're linking the tables correctly. After that, think of how you could be limiting your results to your needs.&lt;/p&gt;

&lt;p&gt;One way to solve the pizza problem is to not use WHERE at all. Instead we can add the condition for the date in our JOIN:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SELECT p.id, p.flavor, COUNT(o.pizza_id) * p.price AS total
FROM shop.pizzas p
LEFT JOIN shop.orders o ON p.id = o.pizza_id
    AND o."date" BETWEEN '2023-05-01' AND '2023-05-31'
GROUP BY p.id, p.flavor
ORDER BY p.flavor


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

id | flavor           | total
-- | ---------------- | -----
1  | Americana        |  7.10
2  | Caprese          |  0.00
3  | Funghi           |  0.00
4  | Margherita       | 11.40
5  | Napoletana       |  0.00
6  | Nutella          |  0.00
7  | Prosciutto       |  0.00
8  | Quattro Formaggi |  0.00
9  | Tonno            |  0.00
10 | Verdure          |  0.00


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

&lt;/div&gt;

&lt;p&gt;With this new query we're limiting our results to the records from May, but we're still returning all pizzas even for those flavors without orders, which is the expected result.&lt;/p&gt;

&lt;p&gt;Review your queries: verify you are linking your tables with the correct JOINs and filtering the results with appropriate WHERE clauses. Keep that in mind, and you'll spend less time fixing your queries, and more time appreciating good pizza! 🍕&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hacktoberfest 2020</title>
      <dc:creator>Douglas Modena</dc:creator>
      <pubDate>Tue, 10 Nov 2020 02:00:25 +0000</pubDate>
      <link>https://dev.to/dmodena/hacktoberfest-2020-2mia</link>
      <guid>https://dev.to/dmodena/hacktoberfest-2020-2mia</guid>
      <description>&lt;p&gt;Hi everyone! This was my second year participating in Hacktoberfest. Last year I got great support from a local dev community, and I was able to contribute to some open source projects.&lt;/p&gt;

&lt;p&gt;Hacktoberfest helped me understand better how to contribute to open source software, and help the community.&lt;/p&gt;

&lt;p&gt;This year I was not only able to contribute to some projects, but also help people who were willing to contribute to one of my projects. It was fun, and a satisfying experience. It even helped me understand better the role of a project maintainer.&lt;/p&gt;

&lt;p&gt;I'm grateful for dev.to, DigitalOcean and Intel for organizing this amazing event!&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
    </item>
  </channel>
</rss>
