<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Ashutosh Biswas - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Ashutosh Biswas - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 22 May 2026 17:39:14 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/ashutoshbw/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What are Type Predicates in TypeScript? Explained with Code examples ]]>
                </title>
                <description>
                    <![CDATA[ Type predicates are an interesting syntactical feature in TypeScript. While they appear in the same place as return type annotations, they look more like short affirmative sentences than typical annotations. This gives you greater control over type c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-are-type-predicates-in-typescript/</link>
                <guid isPermaLink="false">66e069369fc5b51642197aac</guid>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Biswas ]]>
                </dc:creator>
                <pubDate>Tue, 10 Sep 2024 15:43:50 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725630140316/a95bd310-5465-4d0c-85fe-e42b91c2452e.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Type predicates are an interesting syntactical feature in TypeScript. While they appear in the same place as return type annotations, they look more like short affirmative sentences than typical annotations. This gives you greater control over type checking.</p>
<p>With the release of TypeScript 5.5, working with type predicates has become more intuitive now because it can infer them automatically in many cases. But if you're navigating slightly older code-bases, you're likely to encounter handwritten type predicates more often.</p>
<p>In this article, we will briefly explore what type predicates are and why they are useful. Let's start by looking at the problem they solve.</p>
<h2 id="heading-the-problem">The Problem</h2>
<p>The best way to understand the usefulness of type predicates, I believe, is by noticing the problems that arise when we don't have them:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isString</span>(<span class="hljs-params">value: unknown</span>): <span class="hljs-title">boolean</span> </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">padLeft</span>(<span class="hljs-params">padding: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span>, input: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">if</span> (isString(padding)) {
    <span class="hljs-keyword">return</span> padding + input;
        <span class="hljs-comment">//   ^</span>
        <span class="hljs-comment">// string | number</span>
  }
  <span class="hljs-keyword">return</span> <span class="hljs-string">" "</span>.repeat(padding) + input; <span class="hljs-comment">// Opps type error here</span>
                 <span class="hljs-comment">//   ^</span>
                 <span class="hljs-comment">// string | number</span>
}
</code></pre>
<p>Here, the return type of <code>isString</code> is set to <code>boolean</code>, and we use it in a function called <code>padLeft</code> to add padding to the left of an input string. The <code>padding</code> can be either a given string or a specified number of space characters.</p>
<p>You might be wondering why I hard-coded the return type to <code>boolean</code>. This is to illustrate the problem. If you don't add any return type annotation and use the latest version of TypeScript, you won't notice any issue here. For now, bear with me – we'll discuss the version-related differences shortly.</p>
<p>The function will work smoothly at runtime, but TypeScript cannot perform any type narrowing with <code>isString</code>. As a result, the type of <code>padding</code> remains <code>string | number</code> both inside and outside the <code>if</code> statement. This leads to a conflict with <code>repeat</code>'s expectation for its first argument, causing the type error.</p>
<h2 id="heading-the-solution-enter-type-predicates">The Solution: Enter Type Predicates</h2>
<p>Even if you are unfamiliar with the term predicate, you have likely used them before. Predicates in programming are simply functions that return a boolean to answer a yes/no question. Several JavaScript built-in array methods, such as <code>filter</code>, <code>find</code>, <code>every</code>, and <code>some</code>, use predicates to help with decision-making.</p>
<p>Type predicates are a way to make predicates more useful for type narrowing. We can fix the problem by using a type predicate as the return type:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isString</span>(<span class="hljs-params">value: unknown</span>): <span class="hljs-title">value</span> <span class="hljs-title">is</span> <span class="hljs-title">string</span> </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>;
}
</code></pre>
<p>Here the type predicate is <code>value is string</code>. It is saying three things:</p>
<ul>
<li><p>The function is a predicate. So TypeScript will show an error if you try to return anything other than a Boolean value.</p>
</li>
<li><p>If it returns <code>true</code>, then <code>value</code> is of type string.</p>
</li>
<li><p>If it returns <code>false</code>, then <code>value</code> is not of type string.</p>
</li>
</ul>
<p>Type predicates let you create user-defined type guards. Type guards are logical checks that let you refine types to more specific types, aka narrow them. So, the above function is also a user-defined type guard.</p>
<p>Here is the full code:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isString</span>(<span class="hljs-params">value: unknown</span>): <span class="hljs-title">value</span> <span class="hljs-title">is</span> <span class="hljs-title">string</span> </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">padLeft</span>(<span class="hljs-params">padding: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span>, input: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">if</span> (isString(padding)) {
    <span class="hljs-keyword">return</span> padding + input;
        <span class="hljs-comment">//   ^</span>
        <span class="hljs-comment">// string</span>
  }
  <span class="hljs-keyword">return</span> <span class="hljs-string">" "</span>.repeat(padding) + input;
                 <span class="hljs-comment">//   ^</span>
                 <span class="hljs-comment">// number</span>
}
</code></pre>
<p>Here, TypeScript correctly narrows the type of <code>padding</code> inside the <code>if</code> statement and outside of it.</p>
<p>Now let's briefly look at how type predicates worked before TypeScript 5.5 and what this version has improved.</p>
<h2 id="heading-type-predicates-before-typescript-55">Type Predicates Before TypeScript 5.5</h2>
<p>In our previous example, if we don't specify any return type, it will be inferred as <code>boolean</code>:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isString</span>(<span class="hljs-params">value: unknown</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">padLeft</span>(<span class="hljs-params">padding: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span>, input: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">if</span> (isString(padding)) {
    <span class="hljs-keyword">return</span> padding + input;
        <span class="hljs-comment">//   ^</span>
        <span class="hljs-comment">// string | number</span>
  }
  <span class="hljs-keyword">return</span> <span class="hljs-string">" "</span>.repeat(padding) + input; <span class="hljs-comment">// Opps type error here</span>
                 <span class="hljs-comment">//   ^</span>
                 <span class="hljs-comment">// string | number</span>
}
</code></pre>
<p>As a result, we have the same error as when we manually wrote the return type <code>boolean</code>. <a target="_blank" href="https://www.typescriptlang.org/play/?ts=5.4.5#code/GYVwdgxgLglg9mABDAzgZSgJxmA5gCgDcBDAGxAFMAuRcAazDgHcwBKRAbwFgAoRRTBSghMSKAE8ADhTjBEJchUQBeVYgBEKLDlzqA3LwC+vXqEiwEiScQAmAGQrAo+azZs6aYEAFsARhUxEAB9ELWw8ABpkMEkQKBownXZuPmQ5fFQMcIJXdzxWZN5+fkFhUStbPNxEAGpo2KgDVONU0pEkdQ0AOkFpYmdcpNr6uKbDIA">Here is the TypeScript playground link</a> for the above code fragment. Go and hover of the functions or variables for a better feeling of the types. Then see how writing the type predicate solves the problem.</p>
<p>If we don't specify the type predicate, using methods like <code>filter</code> can also result in incorrect type detection:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isString</span>(<span class="hljs-params">value: unknown</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>;
}

<span class="hljs-keyword">const</span> numsOrStrings = [<span class="hljs-number">1</span>, <span class="hljs-string">'hello'</span>, <span class="hljs-number">2</span>, <span class="hljs-string">'world'</span>];
<span class="hljs-comment">//      ^</span>
<span class="hljs-comment">//    strings: (string | number)[]</span>

<span class="hljs-keyword">const</span> strings = numsOrStrings.filter(isString);
<span class="hljs-comment">//      ^</span>
<span class="hljs-comment">//    strings: (string | number)[]</span>
</code></pre>
<p>Now let's see how TypeScript 5.5 improves the situation.</p>
<h2 id="heading-type-predicates-after-typescript-55">Type Predicates After TypeScript 5.5</h2>
<p>One of the top features of TypeScript 5.5 is it can infer type predicates by analyzing the function body. So if you are using TypeScript 5.5 or later, you don't have to write the type predicate as the return type of <code>isString</code>. TypeScript does it for you, and code like what you see in the example below works perfectly fine:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isString</span>(<span class="hljs-params">value: unknown</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> value === <span class="hljs-string">"string"</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">padLeft</span>(<span class="hljs-params">padding: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span>, input: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">if</span> (isString(padding)) {
    <span class="hljs-keyword">return</span> padding + input;
        <span class="hljs-comment">//   ^</span>
        <span class="hljs-comment">// string</span>
  }
  <span class="hljs-keyword">return</span> <span class="hljs-string">" "</span>.repeat(padding) + input; <span class="hljs-comment">// Opps type error here</span>
                 <span class="hljs-comment">//   ^</span>
                 <span class="hljs-comment">// number</span>
}

<span class="hljs-keyword">const</span> numsOrStrings = [<span class="hljs-number">1</span>, <span class="hljs-string">'hello'</span>, <span class="hljs-number">2</span>, <span class="hljs-string">'world'</span>];

<span class="hljs-keyword">const</span> strings = numsOrStrings.filter(isString);
<span class="hljs-comment">//      ^</span>
<span class="hljs-comment">//    strings: string[]</span>

<span class="hljs-keyword">const</span> numbers = numsOrStrings.filter(<span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> !isString(v));
<span class="hljs-comment">//      ^</span>
<span class="hljs-comment">//    numbers: number[]</span>
</code></pre>
<p>I haven't yet found a situation where I'm unhappy with the automatic inference of type predicates. If you do find one, you can always write your own manually.</p>
<h2 id="heading-further-study">Further Study</h2>
<p>In this article, we briefly explored type predicates in TypeScript. If you're interested in learning more and understanding the edge cases, here are the official guides:</p>
<ul>
<li><p><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#inferred-type-predicates">What's New → TypeScript 5.5 → Inferred Type Predicates</a></p>
</li>
<li><p><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates">Handbook → Narrowing → Using type predicates</a></p>
</li>
</ul>
<p>Thanks for reading! See you next time!</p>
<p>Cover photo background is from <a target="_blank" href="https://unsplash.com/@monaeendra?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Mona Eendra</a> on <a target="_blank" href="https://unsplash.com/photos/flowers-beside-yellow-wall-vC8wj_Kphak?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use pnpm – Installation and Common Commands ]]>
                </title>
                <description>
                    <![CDATA[ pnpm is like npm, but it's way faster and more efficient. After all, the starting p stands for _p_erformant. According to its creator, Zoltan Kochan, pnpm "allows you to save gigabytes of disk space." Many popular projects including Next.js, Vite, Sv... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-pnpm/</link>
                <guid isPermaLink="false">66c5f749bae1f0a10743aece</guid>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pnpm ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Biswas ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jan 2024 15:31:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/cover-pnpm-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><em>pnpm</em> is like npm, but it's way faster and more efficient. After all, the starting <em>p</em> stands for _p_erformant.</p>
<p>According to its creator, Zoltan Kochan, pnpm "allows you to save gigabytes of disk space."</p>
<p>Many popular projects including Next.js, Vite, Svelte, and even freeCodeCamp use pnpm. So now is a great time try out this tool if you haven't yet. I'm sure your time will not be wasted.</p>
<p>In this article, I won't go into details of why pnpm is faster and more efficient than npm. You can check out the <a target="_blank" href="https://pnpm.io/motivation">official documentation</a> if you want to know more about that.</p>
<p>The goal of this article is to quickly get you started with pnpm so you can perform your day to day tasks that you previously did with npm or yarn. Grab your favorite cup of tea or coffee ☕️, and let's dive right in! 🚀</p>
<h2 id="heading-how-to-install-pnpm">How to Install pnpm</h2>
<p>I assume you already have a modern version of Node.js installed on your machine. These modern versions come with a command called <code>corepack</code>. It let's you manage your Node package managers. </p>
<p>Yes you read that right! It's an experimental feature of Node but it works pretty well. </p>
<p>So to start using it, you first need to enable it by entering the following command from your terminal, which has the effect of installing pnpm (and also yarn) on your system:</p>
<pre><code class="lang-zsh">corepack <span class="hljs-built_in">enable</span>
</code></pre>
<p>It's that simple. Now if you run <code>pnpm --version</code> you will see the version you have just installed. But this might not be the latest version of pnpm. If this is the case, you can install the latest version of pnpm using this command:</p>
<pre><code class="lang-zsh">corepack prepare pnpm@latest --activate
</code></pre>
<p>Keep in mind that there are many ways to install pnpm on your system, and you can read about all of them in the <a target="_blank" href="https://pnpm.io/installation">installation docs</a>. My favorite is the <code>corepack</code> formula I've shown above.</p>
<h2 id="heading-how-to-configure-your-shell-for-efficiency-optional">How to Configure your Shell for Efficiency (Optional)</h2>
<p>Well, you now have pnpm installed. But the default command line experience can be improved to save you some effort. </p>
<p>Note that this section is optional. If you want you can skip to the next section. But if you are serious about setting it up so that the CLI experience is pleasant, let's learn how to do it.</p>
<h3 id="heading-pnpm-is-hard-to-type-so-set-up-an-alias"><code>pnpm</code> is Hard to Type – So Set Up an Alias</h3>
<p>If you find <code>pnpm</code> hard to type like I do, you can set up an alias to to save you some effort. If you're on Linux or MacOS, just put the following in your shell config (<code>.bashrc</code>, <code>.zshrc</code>, or <code>config.fish</code>):</p>
<pre><code>alias pn=pnpm
</code></pre><p>If you want to set up your alias in Powershell (Windows) you can <a target="_blank" href="https://pnpm.io/installation#adding-a-permanent-alias-in-powershell-windows">see this doc</a>.</p>
<h3 id="heading-how-to-setup-tab-completion">How to Setup Tab-Completion</h3>
<p>There are two ways you can do this in pnpm. Both have their pros and cons.</p>
<p>First I will share with you my favorite method. It's a shell plugin called <code>pnpm-shell-completion</code> and is available for zsh, fish shell, and Powershell core. It only covers the most commonly used commands. If you are Arch Linux and zsh user, you can install it with any AUR helper. For example, if you use <code>yay</code>, run the following command to install it:</p>
<pre><code class="lang-zsh">yay -S pnpm-shell-completion
</code></pre>
<p>Then add the following line in your <code>.zshrc</code> file to load it:</p>
<pre><code class="lang-zsh"><span class="hljs-built_in">source</span> /usr/share/zsh/plugins/pnpm-shell-completion/pnpm-shell-completion.zsh
</code></pre>
<p>Now it should work. If you use any other supported shell, follow the plugin's <a target="_blank" href="https://github.com/g-plane/pnpm-shell-completion">doc</a> to learn how to install it.</p>
<p>The second method comes built-in with pnpm. To setup this style of auto-completion, run the following command:</p>
<pre><code class="lang-shell">pnpm install-completion
</code></pre>
<p>And then follow the steps it gives you. This method covers more commands than the first approach. But it has some limitations – for example it can't auto-complete your <code>package.json</code> scripts. It also, for example, can't auto complete any dependency name that you want to uninstall.</p>
<h2 id="heading-how-to-use-pnpm">How to Use <code>pnpm</code></h2>
<p>Now, you should have pnpm installed with an alias and tab-completion. No more delay – let's see how to use pnpm.</p>
<h3 id="heading-how-to-initialize-a-new-project-using-pnpm">How to Initialize a New Project using <code>pnpm</code></h3>
<p>To get the default <code>package.json</code> in the current directory, run the following command:</p>
<pre><code class="lang-zsh">pnpm init
</code></pre>
<p>Unlike npm, it will not create it interactively and you don't need to specify the <code>-y</code> flag for this.</p>
<h3 id="heading-how-to-install-a-package">How to Install a Package</h3>
<p>To install a package as a dependency, the syntax is:</p>
<pre><code>pnpm add &lt;pkg&gt;
</code></pre><p>To install a package as a dev dependency, you have pass the <code>-D</code> (or <code>--save-dev</code>) flag:</p>
<pre><code>pnpm add -D &lt;pkg&gt;
</code></pre><p>To install a package globally, use the <code>-g</code> flag:</p>
<pre><code>pnpm add -g &lt;pkg&gt;
</code></pre><h3 id="heading-how-to-install-all-dependencies">How to Install All Dependencies</h3>
<p>Suppose you cloned a project from GitHub. It does have a <code>package.json</code> file but no <code>node_modules</code> (you should not track <code>node_modules</code> with Git). Now to install all the dependencies in that <code>package.json</code>, the command is very similar to <code>npm</code>:</p>
<pre><code>pnpm install
</code></pre><p>or</p>
<pre><code>pnpm i
</code></pre><h3 id="heading-how-to-run-a-packagejson-script">How to Run a <code>package.json</code> Script</h3>
<p>This process is also very similar to <code>npm</code>. The explicit way to do it is to use the <code>run</code> command. If you have a script named <code>build</code>, you can execute it with this command:</p>
<pre><code>pnpm run build
</code></pre><p>You can also use <code>pnpm build</code> to do the same thing. This is a shorthand format that can do other things as well. We'll learn more about shorthand very soon in this article.</p>
<h3 id="heading-how-to-run-commands-that-come-with-dependencies">How to Run Commands that Come with Dependencies</h3>
<p>You can run commands that come with dependencies using <code>pnpm exec</code>.</p>
<p>When you install a package, if it has commands specified by the <code>bin</code> field in its <code>package.json</code>, you will get an executable of the same name in your <code>node_modules/.bin</code> directory. Its purpose to execute the corresponding file.</p>
<p><code>pnpm exec</code> prepends <code>./node_modules/.bin</code> to the <code>PATH</code> (that is, <code>PATH=./node_modules/.bin:$PATH</code>) and then executes the given command.</p>
<p>The following is an example that shows installing <code>typescript</code> as a dev dependency and then running the <code>tsc</code> command to create a <code>tsconfig.json</code> file:</p>
<pre><code>pnpm add -D typescript
pnpm exec tsc --init
</code></pre><p>Similar to the <code>pnpm run</code> command, you can also omit <code>exec</code> and just use <code>pnpm tsc</code> to do the same thing. This works when you don't have a conflicting <code>tsc</code> script in your <code>package.json</code>. In the next section we will take a close look at this shorthand syntax.</p>
<p>Note that since <code>pnpm exec</code> has access to all commands resolved by the paths specified in <code>PATH</code>, you may have access to many system commands for example <code>rm</code>, <code>ls</code>, and so on.</p>
<h3 id="heading-how-pnpm-works">How <code>pnpm &lt;command&gt;</code> Works</h3>
<p><code>pnpm &lt;command&gt;</code> works like this:</p>
<ul>
<li>If <code>&lt;command&gt;</code> is a pnpm command (that is <code>add</code>, <code>install</code> and so on), execute that command.</li>
<li>Else if <code>&lt;command&gt;</code> is a script found in <code>package.json</code>, execute <code>pnpm run &lt;command&gt;</code>.</li>
<li>Else execute <code>pnpm exec &lt;command&gt;</code>.</li>
</ul>
<p>So <code>pnpm &lt;command&gt;</code> serves as a convenient shortcut where <code>pnpm exec</code> and <code>pnpm run</code> are explicit commands without fallback.</p>
<h3 id="heading-how-to-update-packages">How to Update Packages</h3>
<p>To update packages to their latest versions based on the specified range in <code>package.json</code>, run this command:</p>
<pre><code>pnpm up
</code></pre><p>To update all dependencies to their latest versions, ignoring ranges specified in <code>package.json</code>, run this:</p>
<pre><code>pnpm up --latest
</code></pre><h3 id="heading-how-to-remove-a-package">How to Remove a Package</h3>
<p>To remove a package from both <code>node_modules</code> and your <code>package.json</code>, you can use <code>pnpm rm</code>. For example if you installed <code>express</code>, you can remove it using:</p>
<pre><code>pnpm rm express
</code></pre><p>To remove a globally installed package, use the <code>-g</code> flag. Below is an example of removing the globally installed package <code>nodemon</code>:</p>
<pre><code>pnpm rm -g nodemon
</code></pre><h2 id="heading-is-there-an-npx-alternative">Is There an <code>npx</code> Alternative?</h2>
<p>Yes – it's the <code>pnpm dlx</code> command. It's very similar to npx. It downloads the specified package from the registry without installing it as a dependency and then runs whatever default command binary it exposes.</p>
<p>For example, you can run the command that <code>cowsay</code> package exposes like below to print ASCII art of a cow saying a string that you pass:</p>
<pre><code>pnpm dlx cowsay hi freeCodeCamp
</code></pre><p>Now you might be wondering, if a package exposes multiple command binaries, what command <code>pnpm dlx</code> chooses as the default? Or how can you explicitly specify a command binary?</p>
<p>Let's see how the default command binary is determined first:</p>
<ul>
<li>If the <code>bin</code> field of <code>package.json</code> has only one entry, then that is used.</li>
<li>Else if there is a command name in the <code>bin</code> field of <code>package.json</code> that matches the package name, ignoring the scope part if any, then that command is used.</li>
<li>Else pnpm can't determine the default command and throws an error with a helpful error message that most likely will answer the second question.</li>
</ul>
<p>To explicitly specify a particular command, you will need to install the package first using the <code>--package</code> option and specify that command after <code>dlx</code>. </p>
<p>For example the package <code>typescript</code> exposes to command binaries <code>tsc</code> and <code>tsserver</code>. Now if you want to run <code>tsc --init</code> to create a <code>tsconfig.json</code> file without having <code>typescript</code> in your <code>node_modules</code> or <code>package.json</code>, you can use <code>pnpm dlx</code> like below:</p>
<pre><code>pnpm --package=typescript dlx tsc --init
</code></pre><h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you've learned what pnpm is and how to install it. We've also covered several common pnpm commands that you will most likely need on a daily basis. </p>
<p>I hope this article helped you get up and running with pnpm. Check out the <a target="_blank" href="https://pnpm.io/motivation">documentation of pnpm</a> to learn more about it.</p>
<p>If you want you can follow me on <a target="_blank" href="https://www.linkedin.com/in/ashutosh-biswas/">LinkedIn</a> and <a target="_blank" href="https://twitter.com/ashutoshbw">Twitter</a> where I share useful coding related things.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What are BNF and EBNF in Programming? ]]>
                </title>
                <description>
                    <![CDATA[ As programmers, we communicate with computers through many languages: Python, JavaScript, SQL, C... you name it. But do you know how the creators of these languages precisely describe their syntax to us, leaving no room for doubt? They could've relie... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-are-bnf-and-ebnf/</link>
                <guid isPermaLink="false">66c5f74ffdf18f48a8c0c35f</guid>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ syntax ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Biswas ]]>
                </dc:creator>
                <pubDate>Mon, 17 Jul 2023 17:26:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/ryan-wallace-azA1hLbjBBo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As programmers, we communicate with computers through many languages: Python, JavaScript, SQL, C... you name it. But do you know how the creators of these languages precisely describe their syntax to us, leaving no room for doubt?</p>
<p>They could've relied on plain English, but that would not be a good solution because of the potential verbosity and ambiguity. So they used specially designed languages for it. </p>
<p>In this article, you'll learn about two of these widely used languages: BNF and EBNF.</p>
<p>Another fascinating aspect of these special languages or notations is that you can write the grammar of your own language using them and give it as input to some magical computer programs called "parser generators". These can output other programs capable of parsing any text according to the grammar you used. How amazing is that? </p>
<p>This feature can save you a lot of time since manually writing such programs is challenging and time-consuming.</p>
<p>Before learning (E)BNF, it's helpful to be able to distinguish between syntax and semantics. So let's start from there.</p>
<h2 id="heading-syntax-vs-semantics-in-programming-languages">Syntax vs Semantics in Programming Languages</h2>
<p>Syntax refers to the structure of the elements of a language based on its type. On the other hand, semantics are all about the meaning.</p>
<p>Something written syntactically correctly in a language can be completely meaningless. And no text can be meaningful if its syntax is incorrect.</p>
<p>Two of the most famous sentences regarding syntax and semantics are <a target="_blank" href="https://en.wikipedia.org/wiki/Colorless_green_ideas_sleep_furiously">composed by Noam Chomsky</a>:</p>
<ol>
<li>Colorless green ideas sleep furiously.</li>
<li>Furiously sleep ideas green colorless.</li>
</ol>
<p>The first sentence's syntax is correct but it's meaningless. And since the second one is syntactically wrong, it is far from being meaningful.</p>
<p>The same is true for programming languages too. Let's look at the following two JavaScript code snippets to see what I mean.</p>
<p>The following code is syntactically correct but semantically wrong because it's not possible to reassign something to a constant variable:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> name = <span class="hljs-string">"Palash"</span>;
name = <span class="hljs-string">"Akash"</span>;
</code></pre>
<p>The following is syntactically incorrect and thus does not even have any chance to be semantically correct.</p>
<pre><code class="lang-js"><span class="hljs-string">"Palash"</span> = <span class="hljs-keyword">const</span> name;
<span class="hljs-string">"Akash"</span> = name;
</code></pre>
<p>You check the syntax of your JavaScript code online with a tool like the <a target="_blank" href="https://esprima.org/demo/validate.html">Esprima Syntax Validator</a>.</p>
<p>There are two more concepts you need to understand before learning to read BNF/EBNF.</p>
<h2 id="heading-terminals-and-non-terminals">Terminals and Non-Terminals</h2>
<p>BNF/EBNF is usually used to specify the grammar of a language. Grammar is a set of <em>rules</em> (also called <em>production rules</em>). Here language refers to nothing but a set of strings that are valid according to the rules of its grammar.</p>
<p>A BNF/EBNF grammar description is an unordered list of rules. <em>Rules</em> are used to define <em>symbols</em> with the help of other symbols.</p>
<p>You can think of <em>symbols</em> as the building blocks of grammar. There are two kinds of symbols:</p>
<ul>
<li><strong>Terminal (or Terminal symbol)</strong>: Terminals are strings written within quotes. They are meant to be used as they are. Nothing is hidden behind them. For example <code>"freeCodeCamp"</code> or <code>"firefly"</code>.</li>
<li><strong>Non-terminal (or Non-terminal symbol)</strong>: Sometimes we need a name to refer to something else. These are called <em>non-terminals</em>. In BNF, <em>non-terminal</em> names are written within angle brackets (for example <code>&lt;statement&gt;</code>), while in EBNF they don't usually use brackets (for example <code>statement</code>).</li>
</ul>
<p>The whole language is derived from a single <em>non-terminal</em> symbol. This is called the <strong>start</strong> or <strong>root</strong> <strong>symbol</strong> of the grammar. By convention, it is written as the first non-terminal in the BNF/EBNF grammar description.</p>
<p>Finally, you are ready to learn BNF. It's easier than you might think it is.</p>
<h2 id="heading-what-is-bnf">What is BNF?</h2>
<p>BNF stands for <strong>B</strong>ackus–<strong>N</strong>aur <strong>F</strong>orm which resulted primarily from the contributions of <a target="_blank" href="https://en.wikipedia.org/wiki/John_Backus">John Backus</a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Peter_Naur">Peter Naur</a>.</p>
<p>The syntax of BNF/EBNF is so simple that many people adopted their styles. So in different places, you will most likely see different styles. If the syntax is different from conventional ones, that's usually documented there. In this article I will use one particular style, just to keep things simple.</p>
<p>Below is an example of a simple <em>production rule</em> in BNF:</p>
<pre><code class="lang-bnf">&lt;something&gt; ::= "content"
</code></pre>
<p>Each rule in BNF (also in ENBF) has three parts:</p>
<ul>
<li><strong>Left-hand side</strong>: Here we write a non-terminal to define it. In the above example, it is <code>&lt;something&gt;</code>.</li>
<li><strong><code>::=</code></strong>: This character group separates the <strong>Left hand side</strong> from <strong>Right hand side</strong>. Read this symbol as "is defined as".</li>
<li><strong>Right-hand side</strong>: The definition of the non-terminal specified on the right-hand side. In the above example, it's <code>"content"</code>.</li>
</ul>
<p>The above <code>&lt;something&gt;</code> is just one thing fixed thing. Let's now see all the ways you can compose a <em>non-terminal</em>.</p>
<h3 id="heading-how-to-compose-a-non-terminal">How to compose a non-terminal</h3>
<p>BNF offers two methods to us:</p>
<ul>
<li>Sequencing</li>
<li>Choice</li>
</ul>
<p>You can just write a combination of one or more terminals or non-terminals in a sequence and the result is their concatenation, with non-terminals being replaced by their content. For example, you can express your breakfast in the following ways:</p>
<pre><code class="lang-bnf">&lt;breakfast&gt; ::= &lt;drink&gt; " and biscuit"
&lt;drink&gt; ::= "tea"
</code></pre>
<p>It means the only option for breakfast for you is <code>"tea and biscuit"</code>. Note that here, the order of symbols is important.</p>
<p>Let's say someday you want to drink coffee instead of tea. In this case, you can express your possible breakfast items like below:</p>
<pre><code class="lang-bnf">&lt;breakfast&gt; ::= &lt;drink&gt; " and biscuit"
&lt;drink&gt; ::= "tea" | "coffee"
</code></pre>
<p>The <code>|</code> operator indicates that the parts separated by it are choices. Which means the non-terminal on the left can be any such part. Here the order is <em>unimportant</em>, that is there is no difference between <code>"tea" | "coffee</code> and <code>"coffee" | "tea"</code>.</p>
<p>That is really all you need to know about BNF to read and understand it and even express the syntax of your own language using it. Believe it or not, it's that simple. And yet it can be used to describe the syntax of many programming languages and other kinds of coding languages.</p>
<p>The thing that makes it possible to break down complex syntax programming languages easily is the ability to define non-terminal symbols recursively. </p>
<p>As a simple example let's see how you express one or more digits in BNF:</p>
<pre><code class="lang-bnf">&lt;digits&gt; ::= &lt;digit&gt; | &lt;digit&gt; &lt;digits&gt;
&lt;digit&gt; ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
</code></pre>
<p>If you want to see a simple real-world example of BNF grammar checkout: <a target="_blank" href="https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions">Semver notation</a>.</p>
<h2 id="heading-what-is-ebnf">What is EBNF?</h2>
<p>BNF is fine, but sometimes it can become verbose and hard to interpret. EBNF (which stands for <strong>E</strong>xtended <strong>B</strong>ackus–<strong>N</strong>aur <strong>F</strong>orm) may help you in those cases. For example, the previous example can be written in EBNF like below:</p>
<pre><code class="lang-ebnf">digits = digit { digit }
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
</code></pre>
<p>The braces above mean that its inner part may be repeated 0 or more times. It frees your mind from getting lost in recursion.</p>
<p>One interesting fact is that everything you can express in EBNF can also be expressed in BNF.</p>
<p>EBNF usually uses a slightly different notation than BNF. For example:</p>
<ul>
<li><code>::=</code> becomes just <code>=</code>.</li>
<li>There are no angle brackets around non-terminals.</li>
</ul>
<pre><code class="lang-ad-info">For concatenation, instead of juxtaposition, some prefer `,` to be more explicit. However, I will not use it here.
</code></pre>
<p>Don't assume that these styles to be universal. There are several variants of them and they are usually clear from the context. The more important thing to focus on is the new operations it offers like the braces we've seen above.</p>
<p>EBNF extends BNF by adding the following 3 operations:</p>
<ul>
<li>Option</li>
<li>Repetition</li>
<li>Grouping</li>
</ul>
<h3 id="heading-option">Option</h3>
<p>Option uses square brackets to make the inner content optional. Example:</p>
<pre><code class="lang-ebnf">thing = "water" [ "melon" ]
</code></pre>
<p>So the above <code>thing</code> is either <code>water</code> or <code>watermelon</code>.</p>
<h3 id="heading-repetition">Repetition</h3>
<p>Curly braces indicate the inner content may be repeated 0 or more times. You have already seen a good example of it above. Below is a very simple one just to make the idea solid in your mind:</p>
<pre><code class="lang-ebnf">long_google = "Goo" { "o" } "gle"
</code></pre>
<p>So <code>"Google"</code>, <code>"Gooogle"</code>, <code>"Gooooooogle"</code> are all valid <code>long_google</code> non-terminal.</p>
<h3 id="heading-grouping">Grouping</h3>
<p>Parentheses can be used to indicate grouping. It means everything they wrap can be replaced with any of the valid strings that the contents of the group represent according to the rules of EBNF. For example:</p>
<pre><code class="lang-ebnf">fly = ("fire" | "fruit") "fly"
</code></pre>
<p>Here  <code>fly</code> is either <code>"firefly"</code> or <code>"fruitfly"</code>.</p>
<p>With BNF we could not do that in one line. It would look like the following in BNF:</p>
<pre><code class="lang-ebnf">&lt;fly&gt; ::= &lt;type&gt; "fly"
&lt;type&gt; ::= "fire" | "fruit"
</code></pre>
<h2 id="heading-the-bnf-playground">The BNF Playground</h2>
<p>There is a very nice online playground for BNF and EBNF: <a target="_blank" href="https://bnfplayground.pauliankline.com/"> Playground</a>.</p>
<p>I recommend you check it out and play with it. It uses a slightly different notation so read the "Grammar Help" section beforehand.</p>
<p>It can test if a string is valid according to the grammar you entered. It can also generate random strings based on your grammar!</p>
<p>For fun this is the syntax of a poem-like text (credit goes to chatGPT):</p>
<pre><code class="lang-ebnf">&lt;poem&gt; ::= &lt;line&gt; | &lt;line&gt; "\n" &lt;poem&gt;
&lt;line&gt; ::= &lt;noun_phrase&gt; " " &lt;verb_phrase&gt; " " &lt;adjective&gt;
&lt;noun_phrase&gt; ::= "the " &lt;adjective&gt; " " &lt;noun&gt; | &lt;noun&gt;
&lt;verb_phrase&gt; ::= &lt;verb&gt; | &lt;verb&gt; " " &lt;adverb&gt;
&lt;adjective&gt; ::= "red" | "blue" | "green" | "yellow"
&lt;noun&gt; ::= "sky" | "sun" | "grass" | "flower"
&lt;verb&gt; ::= "shines" | "glows" | "grows" | "blooms"
&lt;adverb&gt; ::= "brightly" | "slowly" | "vividly" | "peacefully"
</code></pre>
<p>Go ahead and copy-paste it into the playground and press the "Generate Random" button to get some mostly meaningless lines of a grammatically correct poem.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>BNF and EBNF are simple and powerful notations to write what computer scientists call <em>context-free grammar</em>. </p>
<p>In simple terms it means the expansion of a non-terminal is not dependent on the context (surrounding symbols), that is it's context-free. It is the most widely used grammar form to formalize the syntax of coding languages.</p>
<p>Here are some resources you might find interesting:</p>
<ul>
<li><a target="_blank" href="https://tomassetti.me/ebnf/">EBNF: How to Describe the Grammar of a Language</a></li>
<li><a target="_blank" href="https://matt.might.net/articles/grammars-bnf-ebnf/">The language of languages</a></li>
<li>Parser generators:<ul>
<li><a target="_blank" href="https://www.antlr.org/">ANTLR</a>, a very powerful parser generator capable of writing parsers in many languages.</li>
<li>If you are a JavaScript person like me and want to get started with a parser generator, take a look at <a target="_blank" href="https://nearley.js.org/">nearly.js</a> for a gentle start.</li>
</ul>
</li>
</ul>
<p>Below are some real-world grammars written using BNF/EBNF or similar notations that you might find interesting:</p>
<ul>
<li><a target="_blank" href="https://iamwilhelm.github.io/bnf-examples/lisp">Lisp</a></li>
<li><a target="_blank" href="https://www.lua.org/manual/5.4/manual.html#9">Lua</a></li>
<li><a target="_blank" href="https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions">Semver</a></li>
<li><a target="_blank" href="https://tc39.es/ecma262/multipage/grammar-summary.html#sec-grammar-summary">JavaScript</a></li>
<li><a target="_blank" href="https://facebook.github.io/jsx/">JSX</a></li>
<li><a target="_blank" href="https://docs.python.org/3/reference/grammar.html">Python</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/Value_definition_syntax">Value Definition Syntax in CSS</a></li>
</ul>
<p>Thanks for reading. Let me know on <a target="_blank" href="https://twitter.com/ashutoshbw">Twitter</a> if you have any questions or found this article helpful. Happy learning!</p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@accrualbowtie?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Ryan Wallace</a> on <a target="_blank" href="https://unsplash.com/photos/azA1hLbjBBo?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Array Methods – How to Use every() and some() in JS ]]>
                </title>
                <description>
                    <![CDATA[ In JavaScript, every and some help you test if something is true for every element or some elements of an array. In this article, I'll show you how to use these helpful array methods. Table of Contents1How every() and some() Work – an Overview2Param... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-the-every-and-some-array-methods-in-javascript/</link>
                <guid isPermaLink="false">66c5f74cfdf18f48a8c0c35d</guid>
                
                    <category>
                        <![CDATA[ arrays ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Biswas ]]>
                </dc:creator>
                <pubDate>Wed, 10 Aug 2022 15:23:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/cover-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In JavaScript, <code>every</code> and <code>some</code> help you test if something is true for every element or some elements of an array.</p>
<p>In this article, I'll show you how to use these helpful array methods.</p>

<div><h2 id="heading-table-of-contents">Table of Contents</h2><ul><li><span>1</span><a href="#how-every-and-some-work-–-an-overview">How <code>every()</code> and <code>some()</code> Work – an Overview</a></li><li><span>2</span><a href="#parameters-of-every-and-some">Parameters of <code>every</code> and <code>some</code></a><ul><li><span>2.1</span><a href="#predicate"><code>predicate</code></a></li><li><span>2.2</span><a href="#optional-thisarg">Optional <code>thisArg</code></a></li></ul></li><li><span>3</span><a href="#edge-cases-for-every-and-some">Edge cases for <code>every</code> and <code>some</code></a><ul><li><span>3.1</span><a href="#what-happens-when-every-and-some-is-called-on-an-empty-array">What happens when <code>every</code> and <code>some</code> is called on an empty array?</a></li><li><span>3.2</span><a href="#non-existing-elements-are-ignored">Non-existing elements are ignored</a></li><li><span>3.3</span><a href="#mutating-the-array-in-the-predicate">Mutating the array in the predicate</a></li></ul></li><li><span>4</span><a href="#a-challenge-for-you">A challenge for you</a></li></ul><span><a href="https://ashutoshbw.github.io/ftg/" target="_blank">Made with FTG</a></span></div>



<h2 id="how-every-and-some-work-–-an-overview"><span>1</span>How <code>every()</code> and <code>some()</code> Work – an Overview<a href="#how-every-and-some-work-–-an-overview">#</a></h2>

<p>First we need some data to test. For simplicity let's consider an array of numbers:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> nums = [<span class="hljs-number">34</span>, <span class="hljs-number">2</span>, <span class="hljs-number">48</span>, <span class="hljs-number">91</span>, <span class="hljs-number">12</span>, <span class="hljs-number">32</span>];
</code></pre>
<p>Now let's say we want to test if every number in the array is less than <code>100</code>. Using <code>every</code> we can easily test it like below:</p>
<pre><code class="lang-js">nums.every(<span class="hljs-function"><span class="hljs-params">n</span> =&gt;</span> n &lt; <span class="hljs-number">100</span>);
<span class="hljs-comment">// true</span>
</code></pre>
<p>Short and sweet! You can think about what happens here like this:</p>
<ul>
<li><code>every</code> loops over the array elements left to right.<ul>
<li>For each iteration, it calls the given function with the current array element as its 1st argument. </li>
<li>The loop continues until the function returns a <strong><a target="_blank" href="https://www.ashutoshbiswas.dev/blog/truthy-and-falsy/">falsy value</a></strong>. And in that case <code>every</code> returns <code>false</code> – otherwise it returns <code>true</code>.</li>
</ul>
</li>
</ul>
<p><code>some</code> also works very similarly to <code>every</code>:</p>
<ul>
<li><code>some</code> loops over the array elements left to right.<ul>
<li>For each iteration, it calls the given function with the current array element as its 1st argument. </li>
<li>The loop continues until the function returns a <strong><a target="_blank" href="https://www.ashutoshbiswas.dev/blog/truthy-and-falsy/">truthy value</a></strong>. And in that case <code>some</code> returns <code>true</code> – otherwise it returns <code>false</code>.</li>
</ul>
</li>
</ul>
<p>Now let's use <code>some</code> to test if some number in the array is odd:</p>
<pre><code class="lang-js">nums.some(<span class="hljs-function"><span class="hljs-params">n</span> =&gt;</span> n % <span class="hljs-number">2</span> == <span class="hljs-number">1</span>);
<span class="hljs-comment">// true</span>
</code></pre>
<p>That's really true! <code>91</code> is odd.</p>
<p>But this is not the end of the story. These methods have some more depth. Let's dig in.</p>
<h2 id="parameters-of-every-and-some"><span>2</span>Parameters of <code>every</code> and <code>some</code><a href="#parameters-of-every-and-some">#</a></h2>

<p>The way to use <code>every</code> and <code>some</code> array methods is exactly the same. They have the same set of parameters and those parameters also mean identical things. So it's very easy to learn them at once.  </p>
<p>We have already worked with first parameter of these methods which is a function. We call this function <em>predicate</em>.</p>
<blockquote>
<p>In computer science, a <strong><a target="_blank" href="https://www.baeldung.com/cs/predicates">predicate</a></strong> is a function of a set of parameters that returns a boolean as an answer. JavaScript treats the function we give to <code>every</code>/<code>some</code> as a <em>predicate</em>. We can return any type of value we wish, but those are treated as a Boolean, so it's common to call this function a predicate.</p>
</blockquote>
<p>They also have an optional 2nd parameter to control <code>this</code> inside of non-arrow predicates. We call it <code>thisArg</code>.</p>
<p>So you can call these methods in the following ways:</p>
<pre><code class="lang-javascript">arr.every(predicate)
arr.every(predicate, thisArg)

arr.some(predicate)
arr.some(predicate, thisArg)
</code></pre>
<p>Let's see the <code>predicate</code> and the optional <code>thisArg</code> in detail below. </p>
<h3 id="predicate"><span>2.1</span><code>predicate</code><a href="#predicate">#</a></h3>

<p>Through the <code>predicate</code>, <code>every</code>/<code>some</code> not only gives us access to the current array element but also its index and the original array through its parameters like below:</p>
<ul>
<li><strong>1st parameter</strong>: The current array element.</li>
<li><strong>2nd parameter</strong>: The index of the current element.</li>
<li><strong>3rd parameter</strong>: The array itself on which <code>every</code>/<code>some</code> is called.</li>
</ul>
<p>We have only seen the first parameter in action in earlier examples. Let's catch the index and the array by defining two more parameters. This time, let's say we have some T-Shirt data to test if all of them have <code>freeCodeCampe</code> logo:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> tshirts = [
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"S"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"black"</span>, <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"S"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"white"</span>, <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"S"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"teal"</span>,  <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"M"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"black"</span>, <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"M"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"white"</span>, <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"M"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"teal"</span>,  <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"L"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"black"</span>, <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"L"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"white"</span>, <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
  { <span class="hljs-attr">size</span>: <span class="hljs-string">"L"</span>, <span class="hljs-attr">color</span>: <span class="hljs-string">"teal"</span>,  <span class="hljs-attr">logo</span>: <span class="hljs-string">"freeCodeCamp"</span> },
];

tshirts.every(<span class="hljs-function">(<span class="hljs-params">item, i, arr</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(i);
  <span class="hljs-built_in">console</span>.log(arr);
  <span class="hljs-keyword">return</span> item.logo == <span class="hljs-string">"freeCodeCamp"</span>;
})
</code></pre>
<p>Try this out in your console to see the output. And don't forget to play around with <code>some</code> too.</p>
<h3 id="optional-thisarg"><span>2.2</span>Optional <code>thisArg</code><a href="#optional-thisarg">#</a></h3>

<p>If in any case you need to have a particular <code>this</code> value inside your predicate, you can set that with <code>thisArg</code>. Note that is only applicable for non-arrow predicates because arrow functions have no <code>this</code> bindings.</p>
<p>If you omit this argument, <code>this</code> inside the predicate (non-arrow function) works as usual, that is:</p>
<ul>
<li>In strict mode <code>this</code> is <code>undefined</code>.</li>
<li>In sloppy mode <code>this</code> is the <strong>global object</strong> which is <code>window</code> in browser and <code>global</code> in Node.</li>
</ul>
<p>I can't think of any good use case of <code>thisArg</code>. But I think it's good that it exists because now you have control over <code>this</code> inside your predicate. So even if someday there is a need for it you will know that there is a way.</p>
<p> If you have any good ideas for uses of <code>thisArg</code>, please let me know on Twitter :)</p>
<h2 id="edge-cases-for-every-and-some"><span>3</span>Edge cases for <code>every</code> and <code>some</code><a href="#edge-cases-for-every-and-some">#</a></h2>

<h3 id="what-happens-when-every-and-some-is-called-on-an-empty-array"><span>3.1</span>What happens when <code>every</code> and <code>some</code> is called on an empty array?<a href="#what-happens-when-every-and-some-is-called-on-an-empty-array">#</a></h3>

<p>Sometimes the array you want to test might be empty. For example, you fetched an array from an API and it can have an arbitrary number of elements at different times including zero.</p>
<p>For the case of <code>every</code> a <code>true</code> return value can mean two things:</p>
<ul>
<li>If the array has more than zero elements, then all elements of the array satisfies the predicate.</li>
<li>The array has no elements.</li>
</ul>
<p>So if we want we can do crazy things inside the predicate like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/wth-what-the-hell-is-going-on.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myCatsBankAccounts = [];
myCatsBankAccounts.every(<span class="hljs-function"><span class="hljs-params">account</span> =&gt;</span> account.balance &gt; elonMusk.totalWealth)
</code></pre>
<p>And still get <code>true</code> as the return value!</p>
<p>If the array is empty, JavaScript directly returns <code>true</code> without any calls to the predicate.</p>
<p>It's because in logic, you can say anything about the elements of an empty set and that is regarded as true or more precisely <a target="_blank" href="https://en.wikipedia.org/wiki/Vacuous_truth">vacuously true</a>. Such logic might seem nonsense in everyday usage but it's how logic works. Read the wiki page linked above to know more about it.</p>
<p>So if you get <code>true</code> as the the return value of <code>every</code> you should be aware that the array could be empty.</p>
<p><code>some</code> on the other hand, directly returns <code>false</code> on empty arrays without any calls to <code>predicate</code> and without any weirdness.</p>
<h3 id="non-existing-elements-are-ignored"><span>3.2</span>Non-existing elements are ignored<a href="#non-existing-elements-are-ignored">#</a></h3>

<p>If your array has holes in it like below, they are ignored by <code>every</code>/<code>some</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myUntiddyArry = [<span class="hljs-number">1</span>,,,<span class="hljs-number">3</span>,,<span class="hljs-number">42</span>];
</code></pre>
<h3 id="mutating-the-array-in-the-predicate"><span>3.3</span>Mutating the array in the predicate<a href="#mutating-the-array-in-the-predicate">#</a></h3>

<p>I will not discuss this case here, because mutating the original array in most cases just complicates things and makes more room for bugs. </p>
<p>If you really need to or are interested, please read the note in the <a target="_blank" href="https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.every">spec</a> for details.</p>
<h2 id="a-challenge-for-you"><span>4</span>A challenge for you<a href="#a-challenge-for-you">#</a></h2>

<p>Express <code>every</code> with <code>some</code> and <code>some</code> with <code>every</code> in JavaScript.</p>
<p>I hope you will also feel the immense joy and wonder that I got when I discovered this relationship!</p>
<details>
  <summary>Solution</summary>
<p>Let's do it step by step. First let's try to express <code>every</code> with <code>some</code>:</p>
<ul>
<li>For every element of the array, the predicate is true.</li>
<li>It's not true that for some elements of the array the predicate is not true.</li>
</ul>
<p>We can translate that into JavaScript like below:</p>
<pre>const myEvery = (arr, predicate) =&gt; !arr.some(e =&gt; !predicate(e));
</pre>
<p>Now let's express <code>some</code> with <code>every</code>. It's almost the same as before. Just <code>some</code> is replaced by <code>every</code>. Try to understand what is going on:</p>
<ul>
<li>For some elements of the array, the predicate is true.</li>
<li>It's not true that for every element of the array the predicate is not true.</li>
</ul>
<p>In JavaScript:</p>
<pre>const mySome = (arr, predicate) =&gt; !arr.every(e =&gt; !predicate(e));
</pre>
<p>Note that the above implementations also work when <code>arr</code> is empty. And for simplicity, I've excluded other parameters of the <code>predicate</code> and <code>thisArg</code>. Try to add these details yourself, if you are interested. In this process, you might learn one or a few things!</p>
</details>

<p>Thanks for reading! I hope this article was helpful. Check out my other articles <a target="_blank" href="https://www.freecodecamp.org/news/author/ashutoshbw/">here</a>. Let's connect on <a target="_blank" href="https://twitter.com/ashutoshbw">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use fnm – Fast Node Manager ]]>
                </title>
                <description>
                    <![CDATA[ If you've been working with Node for a while, you will most likely discover that your projects – or one you're working on – are written for an older version of Node. That means they won't work as expected with the latest version.  In that case, a Nod... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/fnm-fast-node-manager/</link>
                <guid isPermaLink="false">66c5f743d8153f1027a77508</guid>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Biswas ]]>
                </dc:creator>
                <pubDate>Thu, 09 Jun 2022 15:30:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/rocket-fnm.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you've been working with Node for a while, you will most likely discover that your projects – or one you're working on – are written for an older version of Node. That means they won't work as expected with the latest version. </p>
<p>In that case, a Node version manager can help you save precious time installing and switching back and forth between different Node versions. </p>
<p>Today I will introduce you to <code>fnm</code>(Fast Node Manager), a Node version manager, written in Rust with simplicity and speed in mind. <code>fnm</code> also has cross platform support.</p>
  <h2 id="toc-heading">Table of contents</h2>
  <ul>
    <li>
      <span>1</span>
      <a href="#installation-for-linux-system-and-zsh-shell">Installation for Linux system and <code>zsh</code> shell </a>
      <ul>
        <li><span>1.1</span><a href="#shell-setup">Shell setup</a></li>
        <li>
          <span>1.2</span>
          <a href="#how-to-install-the-completion-script">How to install  the completion script </a>
        </li>
      </ul>
    </li>
    <li>
      <span>2</span>
      <a href="#common-usage-of-fnm">Common usage of <code>fnm</code>
      </a>
      <ul>
        <li>
          <span>2.1</span>
          <a href="#how-to-list-all-remote-node-versions">How to list all remote Node versions </a>
        </li>
        <li>
          <span>2.2</span>
          <a href="#how-to-install-multiple-versions-of-node">How to install multiple versions of Node </a>
        </li>
        <li>
          <span>2.3</span>
          <a href="#how-to-set-aliases-for-a-node-version">How to set aliases for a Node version </a>
        </li>
        <li>
          <span>2.4</span>
          <a href="#how-to-use-a-particular-version-of-node">How to use a particular version of Node </a>
        </li>
        <li>
          <span>2.5</span>
          <a href="#how-to-attach-a-node-version-to-a-project">How to attach a Node version to a project </a>
        </li>
        <li>
          <span>2.6</span>
          <a href="#how-to-uninstall-a-version-of-node">How to uninstall a version of Node</a>
        </li>
      </ul>
    </li>
    <li>
      <span>3</span>
        <a href="#how-to-remove-fnm">How to remove <code>fnm</code></a>
    </li>
    <li>
      <span>4</span>
      <a href="#summary">Summary </a>
    </li>
  </ul>

<h2 id="installation-for-linux-system-and-zsh-shell"><span>1</span>Installation for Linux system and zsh shell
<a href="#installation-for-linux-system-and-zsh-shell">§</a></h2>

<p>Here I will only cover the installation of <code>fnm</code> for Linux systems and the <code>zsh</code> shell. See the <a target="_blank" href="https://github.com/Schniz/fnm">documentation</a> for installation instructions for other platforms and shells.</p>
<p>First make sure <code>curl</code> is installed on your system. Then run the following to install <code>fnm</code>:</p>
<pre><code class="lang-zsh">curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell
</code></pre>
<p>It will install <code>fnm</code> in your <code>$HOME/.fnm/</code> directory.</p>
<p><strong>Updating</strong> <code>fnm</code> is the same as <strong>installing it again</strong> with the above command.</p>
<h3 id="shell-setup">
  <span>1.1</span>Shell setup <a href="#shell-setup">§</a>
</h3>

<p>There is one more important step. Just add the following to your <code>.zshrc</code> file:</p>
<pre><code class="lang-zsh"><span class="hljs-comment"># fnm</span>
<span class="hljs-built_in">export</span> PATH=/home/<span class="hljs-variable">$USER</span>/.fnm:<span class="hljs-variable">$PATH</span>
<span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-subst">$(fnm env --use-on-cd --version-file-strategy=recursive)</span>"</span>
</code></pre>
<h3 id="how-to-install-the-completion-script"><span>1.2</span>How to install the completion script
<a href="#how-to-install-the-completion-script">§</a></h3>

<p>Installing the completion script is <strong>optional</strong>. If you're wondering about the role of this step, here is what it does: it tries to auto-complete the partial command that you type relating to fnm when you press the TAB key. For example if you type <code>fnm ls-</code> and press the TAB key it will auto-complete to <code>fnm ls-remote</code>.</p>
<p><code>fnm</code> comes with all the completion codes for different shells with its binary. You will have to paste that code in a file named <code>_fnm</code> in a directory specified in the <code>FPATH</code> environment variable:</p>
<pre><code class="lang-zsh">fnm completions --shell zsh &gt; &lt;a_fpath_dir&gt;/_fnm
</code></pre>
<p>See the output of <code>echo $FPATH</code> to get all the possible directories and replace <code>&lt;a_fpath_dir&gt;</code> with an actual directory. It is recommend to use a user local path. If there are no such path, you can set one in your <code>.zshrc</code> by adding this line:</p>
<pre><code class="lang-zsh">fpath=(/home/<span class="hljs-variable">$USER</span>/your/favorite/path/here <span class="hljs-variable">$fpath</span>)
</code></pre>
<h2 id="common-usage-of-fnm"><span>2</span>Common usage of <code>fnm</code>
<a href="#common-usage-of-fnm">§</a></h2>

<h3 id="how-to-list-all-remote-node-versions"><span>2.1</span>How to list all remote Node versions
<a href="#how-to-list-all-remote-node-versions">§</a></h3>

<p>To see all the different Node versions you can install, run:</p>
<pre><code class="lang-zsh">fnm ls-remote
</code></pre>
<p>It will print all the versions like below:</p>
<pre><code>.
.
.
v16<span class="hljs-number">.15</span><span class="hljs-number">.0</span> (Gallium)
v16<span class="hljs-number">.15</span><span class="hljs-number">.1</span> (Gallium)
v17<span class="hljs-number">.0</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.0</span><span class="hljs-number">.1</span>
v17<span class="hljs-number">.1</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.2</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.3</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.3</span><span class="hljs-number">.1</span>
v17<span class="hljs-number">.4</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.5</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.6</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.7</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.7</span><span class="hljs-number">.1</span>
v17<span class="hljs-number">.7</span><span class="hljs-number">.2</span>
v17<span class="hljs-number">.8</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.9</span><span class="hljs-number">.0</span>
v17<span class="hljs-number">.9</span><span class="hljs-number">.1</span>
v18<span class="hljs-number">.0</span><span class="hljs-number">.0</span>
v18<span class="hljs-number">.1</span><span class="hljs-number">.0</span>
v18<span class="hljs-number">.2</span><span class="hljs-number">.0</span>
v18<span class="hljs-number">.3</span><span class="hljs-number">.0</span>
</code></pre><h3 id="how-to-install-multiple-versions-of-node"><span>2.2</span>How to install multiple versions of Node
<a href="#how-to-install-multiple-versions-of-node">§</a></h3>

<p>Let's install Node of version <code>v18.3.0</code>:</p>
<pre><code class="lang-zsh">fnm install v18.3.0
</code></pre>
<p>For installing Node of the latest LTS version, you can use the <code>--lts</code> option. So run the following to install it also:</p>
<pre><code>fnm install --lts
</code></pre><p><code>fnm</code> also supports partial version matching. <code>fnm</code> guesses the latest available version from your partial input. For example, if you just do:</p>
<pre><code>fnm install <span class="hljs-number">17</span>
</code></pre><p>It will install the Node of version <code>v17.9.1</code> which is latest available version starting with <code>17</code>. So experiment with the above command.</p>
<p>Let's check your Node version by entering <code>node --version</code> in your terminal. Note that the first installed one is used by default.</p>
<p>Before seeing how to start using a different installed version of Node, let's see how you can set an alias(name) to a version so that you can refer to it easily.</p>
<h3 id="how-to-set-aliases-for-a-node-version"><span>2.3</span>How to set aliases for a Node version
<a href="#how-to-set-aliases-for-a-node-version">§</a></h3>

<p>By default, the first version of Node that you install using <code>fnm</code> receives the <code>default</code> alias.</p>
<p>The syntax to set an alias for a version is:</p>
<pre><code>fnm alias &lt;version&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span></span>
</code></pre><p>If you want to set the alias <code>default</code>, there is a shorthand:</p>
<pre><code>fnm <span class="hljs-keyword">default</span> &lt;version&gt;
</code></pre><p>You can set multiple aliases for a version, too.</p>
<p>The syntax to remove an alias is:</p>
<pre><code>fnm unalias &lt;name&gt;
</code></pre><h3 id="how-to-use-a-particular-version-of-node"><span>2.4</span>How to use a particular version of Node
<a href="#how-to-use-a-particular-version-of-node">§</a></h3>

<p>You can use a Node of a particular version using the <code>use</code> sub-command:</p>
<pre><code class="lang-zsh">fnm use 16
</code></pre>
<p>To check the current Node version, simply run:</p>
<pre><code>fnm current
</code></pre><p>To list all the Node versions that you installed with <code>fnm</code>, run:</p>
<pre><code>fnm ls
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2022/06/fnm-ls-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note that you can bypass <code>fnm</code> and use the system wide installation of Node on your system (if any) by using the <code>system</code>:</p>
<pre><code class="lang-zsh">fnm use system
</code></pre>
<h3 id="how-to-attach-a-node-version-to-a-project"><span>2.5</span>How to attach a Node version to a project
<a href="#how-to-attach-a-node-version-to-a-project">§</a></h3>

<p>You can create a <a target="_blank" href="https://github.com/shadowspawn/node-version-usage"><code>.node-version</code></a> file in the root of your project and just write the desired Node version of that project in that file like below to attach a Node version to it:</p>
<pre><code class="lang-zsh"><span class="hljs-built_in">echo</span> <span class="hljs-string">'v18.3.0'</span> &gt; .node-version
</code></pre>
<p><code>fnm</code> respects this file. So if you are in that directory, you can just use <code>fnm install</code> or <code>fnm use</code> to install or use that version.</p>
<p><code>fnm</code> also respects the <code>.nvmrc</code> file (it is similar to the <code>.node-version</code> file but came from <code>nvm</code> land). So if you used <code>nvm</code> earlier, you will have smooth transition to <code>fnm</code>.</p>
<p><code>fnm</code> can use these dot files to detect Node version and even start using it automatically when using <code>cd</code>, which is really handy in most cases, so I've already enabled them in the shell setup by adding the following flags to the <code>fnm env</code> command:</p>
<ul>
<li><strong><code>--use-on-cd</code></strong>: This flag tells <code>fnm</code> that when you <code>cd</code> into a project root directory, it should automatically use the Node of version specified in <code>.node-version</code>(or <code>.nvmrc</code>). Cool, isn't it?</li>
<li><code>**--version-file-strategy=recursive**</code>: This flag and the <code>recursive</code> value of it basically tells <code>fnm</code> to use the specified Node version in <code>.node-version</code>(or <code>.nvmrc</code>) even when you are in a nested directory and using the <code>use</code> or <code>install</code> sub-command without a version. It also tells <code>fnm</code> to use the Node version aliased to <code>default</code> when you are out of any such project directory and using the <code>use</code> sub-command without a version. Using this flag along with <code>--use-on-cd</code> allows you to have the magic of automatically using or installing the Node of the relevant version(as described here) when you go deeply in and out of such project directories. </li>
</ul>
<p>If these features interfere your workflow, you can remove these flag(s) anytime in your shell setup to turn them off.</p>
<h3 id="how-to-uninstall-a-version-of-node"><span>2.6</span>How to uninstall a version of Node
<a href="#how-to-uninstall-a-version-of-node">§</a></h3>

<p>Uninstalling a version of node is very similar to installing it. You just need to use sub-command <code>uninstall</code> instead of <code>install</code>. That's it.</p>
<h2 id="how-to-remove-fnm"><span>3</span>How to remove <code>fnm</code>
<a href="#how-to-remove-fnm">§</a></h2>

<p>Removing <code>fnm</code> is as simple as removing the <code>.fnm</code> directory from your <code>home</code> and removing its specific config that you added in your shell config file. Remember to also remove the completion script.</p>
<h2 id="summary"><span>4</span>Summary
<a href="#summary">§</a></h2>

<p>Below is a summary of all the commands we have discussed in this article:</p>
<pre><code class="lang-zsh"><span class="hljs-comment"># Listing all remote versions</span>
fnm ls-remote

<span class="hljs-comment"># Listing all installed ones</span>
fnm ls

<span class="hljs-comment"># Installing</span>
fnm install &lt;version&gt;

<span class="hljs-comment"># Uninstalling</span>
fnm uninstall &lt;version&gt;

<span class="hljs-comment"># Installing node of the latest LTS version</span>
fnm install --lts

<span class="hljs-comment"># Setting an alias</span>
fnm <span class="hljs-built_in">alias</span> &lt;version&gt; &lt;name&gt;

<span class="hljs-comment"># Shortcut for setting 'default' as an alias</span>
fnm default &lt;version&gt;

<span class="hljs-comment"># Removing an alias</span>
fnm <span class="hljs-built_in">unalias</span> &lt;name&gt;

<span class="hljs-comment"># Using a Node of a particular version</span>
fnm use &lt;version&gt;

<span class="hljs-comment"># Displaying the version of currently used Node</span>
fnm current
</code></pre>
<p>Also, if you need quick help, <code>fnm</code> has built in help that you can get at any time right from your terminal like below:</p>
<ul>
<li>Help for the <code>fnm</code> command: <code>fnm --help</code></li>
<li>Help for any sub command <code>fnm &lt;sub-command&gt; --help</code></li>
</ul>
<p>If you like <code>fnm</code> don't forget it give it a star on <a target="_blank" href="https://github.com/Schniz/fnm">GitHub</a>. I think it deserves more stars than it has now.</p>
<p>Thanks for reading! If you want you can checkout my <a target="_blank" href="https://www.ashutoshbiswas.dev/">website</a> and follow me on <a target="_blank" href="https://twitter.com/ashutoshbw">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/ashutosh-biswas/">LinkedIn</a>.</p>
<p>Happy Coding 😄</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How the JavaScript reduce and reduceRight Methods Work ]]>
                </title>
                <description>
                    <![CDATA[ reduce and reduceRight are two built-in JavaScript array methods that have a bit of a steep learning curve.  But the very essence of these methods are as simple as the following arithmetic computations. Suppose we have an array of numbers: [1, 2, 3, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-reduce-reduceright-works-javascript/</link>
                <guid isPermaLink="false">66c5f7467a486b4bed798336</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Biswas ]]>
                </dc:creator>
                <pubDate>Fri, 13 May 2022 16:10:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/reduce-cover-with-title-3.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><code>reduce</code> and <code>reduceRight</code> are two built-in JavaScript array methods that have a bit of a steep learning curve. </p>
<p>But the very essence of these methods are as simple as the following arithmetic computations.</p>
<p>Suppose we have an array of numbers:</p>
<pre><code class="lang-js">[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]
</code></pre>
<p>And we want to get the sum of them.</p>
<p>The <code>reduce</code> way to get the sum is similar to:</p>
<p>((((1) + 2) + 3) + 4)</p>

<p>Whereas the <code>reduceRight</code> way to get the sum is similar to:</p>
<p>((((4) + 3) + 2) + 1)</p>

<p>With <code>reduce</code> and <code>reduceRight</code>, you can define your own +. Array elements can be anything too. Sounds exciting, right?</p>
<p>Think of <code>reduce</code> and <code>reduceRight</code> as nothing but a generalization of the above arithmetic patterns. In this article we will cover all the important details.</p>
<p>This article takes an easy-to-digest algorithmic approach to show you how reducing works in JavaScript. </p>
<p>I've also created a video to show you how these methods work. Check it out if want to learn the concepts from a more visual angle:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/o43livPsWn4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
  <li>
    <span>1</span><a href="#what-is-reduced-to-what">What is reduced to what? </a>
  </li>

  <li>
    <span>2</span><a href="#parameters-of-reduce-reduceright">Parameters of <code>reduce</code>/<code>reduceRight</code>
    </a>
  </li>

  <li>
    <span>3</span><a href="#understanding-reduce-reduceright-with-a-diagram">Understanding <code>reduce</code>/<code>reduceRight</code> with a diagram
    </a>
  </li>

  <li>
    <span>4</span><a href="#the-algorithm-of-reduce-reduceright">The algorithm of <code>reduce</code>/<code>reduceRight</code>
    </a>
  </li>

  <li>
    <span>5</span><a href="#excercises">Excercises </a>

    <ul>
      <li>
        <span>5.1</span><a href="#flat-nested-array">Flat nested array </a>
      </li>

      <li>
        <span>5.2</span><a href="#remove-duplicate-items-from-an-array">Remove duplicate items from an array
        </a>
      </li>

      <li>
        <span>5.3</span><a href="#reverse-an-array-without-mutating-it">Reverse an array without mutating it
        </a>
      </li>
    </ul>
  </li>

  <li>
    <span>6</span><a href="#conclusion">Conclusion </a>
  </li>
</ul>


<h2 id="what-is-reduced-to-what"><span>1</span>What is reduced to what?
<a href="#what-is-reduced-to-what">§</a></h2>

<p>You might be wondering, "What kind of reduction happens when using <code>reduce</code> or <code>reduceRight</code>?"</p>
<p>Here, reduction reflects a particular way of transforming (which we will see in detail) the elements in an array to a single value similar to the arithmetic computations we have seen above. </p>
<p>But note that the output value can be anything. So it can be a value that looks bigger than the original array on which the method is called.</p>
<p>In <em>functional programming</em> languages, the idea of reducing has many <a target="_blank" href="https://en.wikipedia.org/wiki/Fold_(higher-order_function)">other names</a> such as <strong>fold</strong>, <strong>accumulate</strong>, <strong>aggregate</strong>, <strong>compress</strong> and even <strong>inject</strong>.</p>
<h2 id="parameters-of-reduce-reduceright"><span>2</span>Parameters of <code>reduce</code>/<code>reduceRight</code>
<a href="#parameters-of-reduce-reduceright">§</a></h2>

<p>These methods both have the same rules for calling them. So it's easy to learn them together. Let's see how they can be called:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> myArray      = [<span class="hljs-comment">/* an array */</span>];
<span class="hljs-keyword">let</span> callbackfn   = <span class="hljs-comment">/* A function value */</span> ;
<span class="hljs-keyword">let</span> initialvalue = <span class="hljs-comment">/* any value */</span> ;

myArray.reduce(callbackfn)
myArray.reduce(callbackfn, initialValue)

myArray.reduceRight(callbackfn)
myArray.reduceRight(callbackfn, initialValue)
</code></pre>
<p>Here the usage of the parameters of <code>reduce</code>/<code>reduceRight</code> is explained through the <code>callbackfn</code> and <code>initialValue</code> variables:</p>
<p><strong><code>callbackfn</code></strong>: It must be a function. While iterating over the array, for each element, <code>reduce</code>/<code>reduceRight</code> calls <code>callbackfn</code> with 4 arguments. Let's assume the variables <code>previousValue</code>, <code>currentElement</code>, <code>index</code> and <code>array</code> hold the values of those arguments, respectively. So the internal call to <code>callbackfn</code> looks like this:</p>
<pre><code class="lang-js">callbackfn(previousValue, currentElement, index, array)
</code></pre>
<p>Now let's see the meaning of those values:</p>
<ol>
<li><code>previousValue</code>: This is also known as the <em>accumulator</em>. Long story short, this value represents the "work in progress" of the return value of the method. What this value is made up of will become completely clear when you study the algorithm presented later in this article.</li>
<li><code>currentElement</code>: The current element.</li>
<li><code>index</code>: The index of the current element.</li>
<li><code>array</code>: <code>myArray</code>.</li>
</ol>
<p><strong>Return value of <code>callbackfn</code></strong>: For the last call to <code>callbackfn</code>, its return value becomes the return value of <code>reduce</code>/<code>reduceRight</code>. Otherwise, its return value will be given as <code>previousValue</code> for the next call to <code>callbackfn</code>.</p>
<p>And finally, <strong><code>initialValue</code></strong>: This is an optional initial value for <code>previousValue</code> (the accumulator). If it's given, and <code>myArray</code> has some elements in it, the first call to <code>callbackfn</code> will receive this value as its <code>previousValue</code>.</p>
<p><strong>Note</strong>: The <code>callbackfn</code> is usually called a <strong>reducer function</strong>(or just <strong>reducer</strong> for short).</p>
<h2 id="understanding-reduce-reduceright-with-a-diagram"><span>3</span>Understanding <code>reduce</code>/<code>reduceRight</code> with a diagram
<a href="#understanding-reduce-reduceright-with-a-diagram">§</a></h2>

<p>The only difference between <code>reduce</code> and <code>reduceRight</code> is the direction of the iteration. <code>reduce</code> iterates over the array elements left to right. And <code>reduceRight</code> iterates over the elements right to left.</p>
<p>Let's see how you can use <code>reduce</code>/<code>reduceRight</code> to join an array of strings. Note how the final output is reached by joining the array elements step by step in both directions:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/reduce-diagram1-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A diagram showing the differences between <code>reduce</code> and <code>reduceRight</code></em></p>
<p>Here note that:</p>
<ul>
<li><code>acc</code> is used to access <code>previousValue</code> .</li>
<li><code>curVal</code> is used to access <code>currentElement</code>.</li>
<li>The circular shaped input to <em><strong><code>r</code></strong></em> represents <code>curVal</code>.</li>
<li>The rectangular shaped input to <em><strong><code>r</code></strong></em> represents <code>acc</code> or the accumulator.</li>
<li>Initial values are in rectangular shapes, because they are received by <code>**_r_**</code> as <code>acc</code>s.</li>
</ul>
<h2 id="the-algorithm-of-reduce-reduceright"><span>4</span>The algorithm of <code>reduce</code>/<code>reduceRight</code>
<a href="#the-algorithm-of-reduce-reduceright">§</a></h2>

<p>The 29 line algorithm below might look intimidating at first glance. But you'll likely find it much easier to understand it than digesting globs of long sentences explaining the intricate details of these methods.</p>
<p><strong>Note</strong>: The algorithm described here has the context of the "<a target="_blank" href="https://www.freecodecamp.org/news/how-reduce-reduceright-works-javascript/#parameters-of-reduce-reduceright">Parameters of reduce/reduceRight</a>" section. (That is, the variables <code>myArray</code>, <code>callbackfn</code> and <code>initialValue</code> come from that section.)</p>
<p>So relax, enjoy the steps, and don't forget to experiment in the console:</p>
<div><ul><div></div><li><div></div><div>1</div>If <code>initialValue</code> is present,<ul><li><div></div><div>2</div>If <code>myArray</code> has no elements, <ul><li><div></div><div>3</div>Return <code>initialValue</code>.</li></ul></li><li><div></div><div>4</div>Else <ul><li><div></div><div>5</div>Let <code>accumulator</code> be <code>initialValue</code>.</li><li><div></div><div>6</div>If the method is <code>reduce</code>,<ul><li><div></div><div>7</div>Let <code>startIndex</code> be the index of the leftmost element of <code>myArray</code>.</li></ul></li><li><div></div><div>8</div>If the method is <code>reduceRight</code>,<ul><li><div></div><div>9</div>Let <code>startIndex</code> be the index of the rightmost element of <code>myArray</code>.</li></ul></li></ul></li></ul></li><li><div></div><div>10</div>Else<ul><li><div></div><div>11</div>If <code>myArray</code> has no elements, <ul><li><div></div><div>12</div>Throw <code>TypeError</code>.</li></ul></li><li><div></div><div>13</div>Else if <code>myArray</code> has just only one element, <ul><li><div></div><div>14</div>Return that element.</li></ul></li><li><div></div><div>15</div>Else<ul><li><div></div><div>16</div>If the method is <code>reduce</code>,<ul><li><div></div><div>17</div>Let <code>accumulator</code> be the leftmost element of <code>myArray</code>.</li><li><div></div><div>18</div>Let <code>startIndex</code> be the index of the element that comes right after the leftmost element of <code>myArray</code>.</li></ul></li><li><div></div><div>19</div>If the method is <code>reduceRight</code>,<ul><li><div></div><div>20</div>Let <code>accumulator</code> be the rightmost element of <code>myArray</code>.</li><li><div></div><div>21</div>Let <code>startIndex</code> be the index of the element that comes right before the rightmost element of <code>myArray</code>.</li></ul></li></ul></li></ul></li><li><div></div><div>22</div>&nbsp;</li><li><div></div><div>23</div>If the method is <code>reduce</code>,<ul><li><div></div><div>24</div>In left to right order, for each element of <code>myArray</code> such that it's index <code>i</code> ≥ <code>startingIndex</code>,<ul><li><div></div><div>25</div>Set <code>accumulator</code> to <code>callbackfn(accumulator, myArray[i], i, myArray)</code>. </li></ul></li></ul></li><li><div></div><div>26</div>If the method is <code>reduceRight</code>,<ul><li><div></div><div>27</div>In right to left order, for each element of <code>myArray</code> such that it's index <code>i</code> ≤ <code>startingIndex</code>,<ul><li><div></div><div>28</div>Set <code>accumulator</code> to <code>callbackfn(accumulator, myArray[i], i, myArray)</code>. </li></ul></li></ul></li><li><div></div><div>29</div>Return <code>accumulator</code>.<div></div></li></ul></div>

<p><strong>Note</strong>: An array can have a length greater than <code>0</code> but no elements. Such empty places in the array are usually called <em>holes</em> in the array. For example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> arr = [,,,,];
<span class="hljs-built_in">console</span>.log(arr.length);
<span class="hljs-comment">// 4</span>

<span class="hljs-comment">// note that trailing comma doesn't increase the length.</span>
<span class="hljs-comment">// This feature enables us to add a new element quickly.</span>
</code></pre>
<p>These methods only call <code>callbackfn</code> for elements of <code>myArray</code> which actually exist. For example if you have an array like <code>[1,,3,,5]</code>, they will not consider the non-existing elements at indices <code>1</code> and <code>3</code>. Try to guess what will be logged after running the following:</p>
<pre><code class="lang-js">[,,,<span class="hljs-number">3</span>,,,<span class="hljs-number">4</span>].reduce(<span class="hljs-function">(<span class="hljs-params">_, cv, i</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(i);
});
</code></pre>
<p>If you said <code>6</code>, you are right!</p>
<p>⚠️ <strong>Warning</strong>: It is not recommended to modify <code>myArray</code> inside of <code>callbackfn</code> because it complicates the logic of your code and thus increases the possibility of bugs.</p>
<p>If you've read and understood this far, congratulations! Now you should have a solid understanding of how <code>reduce</code>/<code>reduceRight</code> works. </p>
<p>It's a great time to solve some problems to get used to <code>reduce</code>/<code>reduceRight</code>. Before seeing the solutions, solve them yourself or at least spend some time thinking about it.</p>
<h2 id="excercises"><span>5</span>Excercises
<a href="#excercises">§</a></h2>

<h3 id="flat-nested-array"><span>5.1</span>Flat nested array
<a href="#flat-nested-array">§</a></h3>

<p>Write a function <code>flatten</code> that can flat a nested array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> arr = [<span class="hljs-number">1</span>, [<span class="hljs-number">2</span>, [<span class="hljs-number">3</span>], [[<span class="hljs-number">4</span>], <span class="hljs-number">5</span>], <span class="hljs-number">6</span>]];
<span class="hljs-built_in">console</span>.log(flatten(arr));
<span class="hljs-comment">// [1, 2, 3, 4, 5, 6]</span>
</code></pre>
<details>
  <summary>
    <b>Solution</b>
  </summary>
  <pre>    <code class=" language-js">
const flatten = (arr) =&gt; 
  arr.reduce((acc, curVal) =&gt;
    acc.concat(Array.isArray(curVal) ? flatten(curVal) : curVal), []);
    </code>
  </pre>
</details>


<h3 id="remove-duplicate-items-from-an-array"><span>5.2</span>Remove duplicate items from an array
<a href="#remove-duplicate-items-from-an-array">§</a></h3>

<p>Write a function <code>rmDuplicates</code> that removes the duplicate items like below:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(rmDuplicates([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">4</span>, <span class="hljs-number">4</span>]));
<span class="hljs-comment">// [1, 2, 3, 4]</span>
</code></pre>
<details>
  <summary>
    <b>Solution</b>
  </summary>
  <pre>    <code class=" language-js">
const rmDuplicates = arr =&gt; 
  arr.reduce((p, c) =&gt; p.includes(c) ? p : p.concat(c), []);
    </code>
  </pre>
</details>


<h3 id="reverse-an-array-without-mutating-it"><span>5.3</span>Reverse an array without mutating it
<a href="#reverse-an-array-without-mutating-it">§</a></h3>

<p>There is a built-in <code>reverse</code> array method to reverse arrays. But it mutates the original array. Use <code>reduceRight</code> to reverse an array without mutating it.</p>
<details>
  <summary>
    <b>Solution</b>
  </summary>
  <pre>    <code class=" language-js">
let arr = [1, 2, 3];

let reversedArr = arr.reduceRight((acc, curVal) =&gt; [...acc, curVal], []);

console.log(arr);
// [1, 2, 3]

console.log(reversedArr);
// [3, 2, 1]
    </code>
  </pre>
  <p>
    Note that by reversing array this way you will lose all the holes in the
    array.
  </p>
</details>


<h2 id="conclusion"><span>6</span>Conclusion
<a href="#conclusion">§</a></h2>

<p>When <code>reduce</code>/<code>reduceRight</code> calls <code>callbackfn</code> internally we can call those patterns of calling it "normal behaviors" and we can treat other scenarios as edge cases. These can be summarized in the table below:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Initial value</td><td>Number of elements</td><td>Output</td></tr>
</thead>
<tbody>
<tr>
<td>Present</td><td>0</td><td><strong>Edge case</strong>: Initial value</td></tr>
<tr>
<td>Present</td><td>Greater than 0</td><td><strong>Normal behavior</strong> </td></tr>
<tr>
<td>Absent</td><td>0</td><td><strong>Edge case</strong>: TypeError</td></tr>
<tr>
<td>Absent</td><td>1</td><td><strong>Edge case</strong>: That element</td></tr>
<tr>
<td>Absent</td><td>Greater than 1</td><td><strong>Normal behavior</strong> </td></tr>
</tbody>
</table>
</div><p>Learning <code>reduce</code>/<code>reduceRight</code> is a little bit more involved than other higher order array methods. But it's worth your time to learn it well. </p>
<p>Thank you for reading! I hope this article was helpful. If you want you can checkout my <a target="_blank" href="https://www.ashutoshbiswas.dev/">website</a> and follow me on <a target="_blank" href="https://twitter.com/ashutoshbw">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/ashutosh-biswas/">LinkedIn</a>.</p>
<p>Happy reducing 😃</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
