<?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[ Ramda - 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[ Ramda - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 27 May 2026 16:22:22 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/ramda/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Yet Another 10 Utility Functions Made with Reduce ]]>
                </title>
                <description>
                    <![CDATA[ By Yazeed Bzadough Thirty functions total! This is my third article on Utility Functions Made with Reduce. Part one (10 functions) Part two (10 functions) Altogether we now have thirty helper functions made using JavaScript's reduce. For more detai... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/yet-another-10-utils-using-reduce/</link>
                <guid isPermaLink="false">66d461c07df3a1f32ee7f8c4</guid>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ramda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 11 Nov 2019 12:59:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/Yet-Another-10-Utility-Functions.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yazeed Bzadough</p>
<p>Thirty functions total!</p>
<p>This is my third article on Utility Functions Made with Reduce.</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/news/10-js-util-functions-in-reduce/">Part one</a> (10 functions)</li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/10-more-js-utils-using-reduce/">Part two</a> (10 functions)</li>
</ul>
<p>Altogether we now have <em>thirty</em> helper functions made using JavaScript's <code>reduce</code>. For more detail on <code>reduce</code> itself, consider reading my <a target="_blank" href="https://www.yazeedb.com/posts/learn-reduce-in-10-minutes">tutorial on it</a>.</p>
<p>The functions listed below were inspired by the amazing <a target="_blank" href="https://ramdajs.com/">RamdaJS</a> library. I also wrote unit tests to ensure correct behavior, which you can find on <a target="_blank" href="https://github.com/yazeedb/js-utils-using-reduce">my GitHub</a>.</p>
<h2 id="heading-1-adjust">1. adjust</h2>
<h3 id="heading-parameters">Parameters</h3>
<ol>
<li><code>index</code> - Index of source array</li>
<li><code>fn</code> - Function to apply at that <code>index</code></li>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description">Description</h3>
<p>Applies a function to the value at the given index. Returns the original array if provided index is out of bounds.</p>
<h3 id="heading-usage">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> double = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">2</span>;

adjust(<span class="hljs-number">1</span>, double, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [1, 4, 3]</span>

adjust(<span class="hljs-number">4</span>, double, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [1, 2, 3]</span>
</code></pre>
<h3 id="heading-implementation">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> adjust = <span class="hljs-function">(<span class="hljs-params">index, fn, list</span>) =&gt;</span>
  list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value, sourceArrayIndex</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> valueToUse = sourceArrayIndex === index ? fn(value) : value;

    acc.push(valueToUse);

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h2 id="heading-2-frompairs">2. fromPairs</h2>
<h3 id="heading-parameters-1">Parameters</h3>
<ol>
<li><code>pairs</code> - A list of key-value pairs.</li>
</ol>
<h3 id="heading-description-1">Description</h3>
<p>Creates an object from a list of key-value pairs.</p>
<h3 id="heading-usage-1">Usage</h3>
<pre><code class="lang-js">fromPairs([[<span class="hljs-string">'a'</span>, <span class="hljs-number">1</span>], [<span class="hljs-string">'b'</span>, <span class="hljs-number">2</span>], [<span class="hljs-string">'c'</span>, <span class="hljs-number">3</span>]]);
<span class="hljs-comment">// { a: 1, b: 2, c: 3 }</span>
</code></pre>
<h3 id="heading-implementation-1">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fromPairs = <span class="hljs-function">(<span class="hljs-params">pairs</span>) =&gt;</span>
  pairs.reduce(<span class="hljs-function">(<span class="hljs-params">acc, currentPair</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> [key, value] = currentPair;

    acc[key] = value;

    <span class="hljs-keyword">return</span> acc;
  }, {});
</code></pre>
<h2 id="heading-3-range">3. range</h2>
<h3 id="heading-parameters-2">Parameters</h3>
<ol>
<li><code>from</code> - Starting number.</li>
<li><code>to</code> - Ending number.</li>
</ol>
<h3 id="heading-description-2">Description</h3>
<p>Returns a list of numbers from a given range.</p>
<h3 id="heading-usage-2">Usage</h3>
<pre><code class="lang-js">range(<span class="hljs-number">1</span>, <span class="hljs-number">5</span>);
<span class="hljs-comment">// [1, 2, 3, 4, 5]</span>
</code></pre>
<h3 id="heading-implementation-2">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> range = <span class="hljs-function">(<span class="hljs-params"><span class="hljs-keyword">from</span>, to</span>) =&gt;</span>
  <span class="hljs-built_in">Array</span>.from({ <span class="hljs-attr">length</span>: to - <span class="hljs-keyword">from</span> + <span class="hljs-number">1</span> }).reduce(<span class="hljs-function">(<span class="hljs-params">acc, _, index</span>) =&gt;</span> {
    acc.push(<span class="hljs-keyword">from</span> + index);

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h2 id="heading-4-repeat">4. repeat</h2>
<h3 id="heading-parameters-3">Parameters</h3>
<ol>
<li><code>item</code> - Item to repeat.</li>
<li><code>times</code> - Number of times to repeat.</li>
</ol>
<h3 id="heading-description-3">Description</h3>
<p>Returns a list of a given value N times.</p>
<h3 id="heading-usage-3">Usage</h3>
<pre><code class="lang-js">repeat({ <span class="hljs-attr">favoriteLanguage</span>: <span class="hljs-string">'JavaScript'</span> }, <span class="hljs-number">2</span>);

<span class="hljs-comment">/*
[{
    favoriteLanguage: 'JavaScript'
}, {
    favoriteLanguage: 'JavaScript'
}],
*/</span>
</code></pre>
<h3 id="heading-implementation-3">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> repeat = <span class="hljs-function">(<span class="hljs-params">item, times</span>) =&gt;</span>
  <span class="hljs-built_in">Array</span>.from({ <span class="hljs-attr">length</span>: times }).reduce(<span class="hljs-function">(<span class="hljs-params">acc</span>) =&gt;</span> {
    acc.push(item);

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h2 id="heading-5-times">5. times</h2>
<h3 id="heading-parameters-4">Parameters</h3>
<ol>
<li><code>fn</code> - Function to call.</li>
<li><code>numTimes</code> - Number of times to call that function.</li>
</ol>
<h3 id="heading-description-4">Description</h3>
<p>Calls a given function N times. The <code>fn</code> provided receives the current index as a parameter.</p>
<h3 id="heading-usage-4">Usage</h3>
<pre><code class="lang-js">times(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">2</span>, <span class="hljs-number">3</span>);
<span class="hljs-comment">// [0, 2, 4]</span>
</code></pre>
<h3 id="heading-implementation-4">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> times = <span class="hljs-function">(<span class="hljs-params">fn, numTimes</span>) =&gt;</span>
  <span class="hljs-built_in">Array</span>.from({ <span class="hljs-attr">length</span>: numTimes }).reduce(<span class="hljs-function">(<span class="hljs-params">acc, _, index</span>) =&gt;</span> {
    acc.push(fn(index));

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h2 id="heading-6-deduplicate">6. deduplicate</h2>
<h3 id="heading-parameters-5">Parameters</h3>
<ol>
<li><code>items</code> - List of items.</li>
</ol>
<h3 id="heading-description-5">Description</h3>
<p>Deduplicates the items in a list.</p>
<h3 id="heading-usage-5">Usage</h3>
<pre><code class="lang-js">deduplicate([[<span class="hljs-number">1</span>], [<span class="hljs-number">1</span>], { <span class="hljs-attr">hello</span>: <span class="hljs-string">'world'</span> }, { <span class="hljs-attr">hello</span>: <span class="hljs-string">'world'</span> }]);
<span class="hljs-comment">// [[1], { hello: 'world' }]</span>
</code></pre>
<h3 id="heading-implementation-5">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> deduplicate = <span class="hljs-function">(<span class="hljs-params">items</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> cache = {};

  <span class="hljs-keyword">return</span> items.reduce(<span class="hljs-function">(<span class="hljs-params">acc, item</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> alreadyIncluded = cache[item] === <span class="hljs-literal">true</span>;

    <span class="hljs-keyword">if</span> (!alreadyIncluded) {
      cache[item] = <span class="hljs-literal">true</span>;
      acc.push(item);
    }

    <span class="hljs-keyword">return</span> acc;
  }, []);
};
</code></pre>
<h2 id="heading-7-reverse">7. reverse</h2>
<h3 id="heading-parameters-6">Parameters</h3>
<ol>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-6">Description</h3>
<p>Reverses a list <em>without</em> mutating it by returning a new list, unlike the native <code>Array.reverse</code> method.</p>
<h3 id="heading-usage-6">Usage</h3>
<pre><code class="lang-js">reverse([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [3, 2, 1]</span>
</code></pre>
<h3 id="heading-implementation-6">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> reverse = <span class="hljs-function">(<span class="hljs-params">list</span>) =&gt;</span>
  list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, _, index</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> reverseIndex = list.length - index - <span class="hljs-number">1</span>;
    <span class="hljs-keyword">const</span> reverseValue = list[reverseIndex];

    acc.push(reverseValue);

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h2 id="heading-8-insertall">8. insertAll</h2>
<h3 id="heading-parameters-7">Parameters</h3>
<ol>
<li><code>index</code> - Index to insert at.</li>
<li><code>subList</code> - List to insert.</li>
<li><code>sourceList</code> - Source list.</li>
</ol>
<h3 id="heading-description-7">Description</h3>
<p>Inserts a sub-list into a list at the given index. Appends to the end of the list if index is too large.</p>
<h3 id="heading-usage-7">Usage</h3>
<pre><code class="lang-js">insertAll(<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">1</span>, <span class="hljs-number">5</span>]);
<span class="hljs-comment">// [1, 2, 3, 4, 5]</span>

insertAll(<span class="hljs-number">10</span>, [<span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>], [<span class="hljs-number">1</span>, <span class="hljs-number">5</span>]);
<span class="hljs-comment">// [1, 5, 2, 3, 4]</span>
</code></pre>
<h3 id="heading-implementation-7">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> insertAll = <span class="hljs-function">(<span class="hljs-params">index, subList, sourceList</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (index &gt; sourceList.length - <span class="hljs-number">1</span>) {
    <span class="hljs-keyword">return</span> sourceList.concat(subList);
  }

  <span class="hljs-keyword">return</span> sourceList.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value, sourceArrayIndex</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (index === sourceArrayIndex) {
      acc.push(...subList, value);
    } <span class="hljs-keyword">else</span> {
      acc.push(value);
    }

    <span class="hljs-keyword">return</span> acc;
  }, []);
};
</code></pre>
<h2 id="heading-9-mergeall">9. mergeAll</h2>
<h3 id="heading-parameters-8">Parameters</h3>
<ol>
<li><code>objectList</code> - List of objects to merge.</li>
</ol>
<h3 id="heading-description-8">Description</h3>
<p>Merges a list of objects into one.</p>
<h3 id="heading-usage-8">Usage</h3>
<pre><code class="lang-js">mergeAll([
    { <span class="hljs-attr">js</span>: <span class="hljs-string">'reduce'</span> },
    { <span class="hljs-attr">elm</span>: <span class="hljs-string">'fold'</span> },
    { <span class="hljs-attr">java</span>: <span class="hljs-string">'collect'</span> },
    { <span class="hljs-attr">js</span>: <span class="hljs-string">'reduce'</span> }
]);

<span class="hljs-comment">/*
{
    js: 'reduce',
    elm: 'fold',
    java: 'collect'
}
*/</span>
</code></pre>
<h3 id="heading-implementation-8">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> mergeAll = <span class="hljs-function">(<span class="hljs-params">objectList</span>) =&gt;</span>
  objectList.reduce(<span class="hljs-function">(<span class="hljs-params">acc, obj</span>) =&gt;</span> {
    <span class="hljs-built_in">Object</span>.keys(obj).forEach(<span class="hljs-function">(<span class="hljs-params">key</span>) =&gt;</span> {
      acc[key] = obj[key];
    });

    <span class="hljs-keyword">return</span> acc;
  }, {});
</code></pre>
<h2 id="heading-10-xprod">10. xprod</h2>
<h3 id="heading-parameters-9">Parameters</h3>
<ol>
<li><code>list1</code> - List of items.</li>
<li><code>list2</code> - List of items.</li>
</ol>
<h3 id="heading-description-9">Description</h3>
<p>Given a list, returns a new list of all possible pairs.</p>
<h3 id="heading-usage-9">Usage</h3>
<pre><code class="lang-js">xprod([<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'World'</span>], [<span class="hljs-string">'JavaScript'</span>, <span class="hljs-string">'Reduce'</span>]);
<span class="hljs-comment">/*
[
  ['Hello', 'JavaScript'],
  ['Hello', 'Reduce'],
  ['World', 'JavaScript'],
  ['World', 'Reduce']
]
*/</span>
</code></pre>
<h3 id="heading-implementation-9">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> xprod = <span class="hljs-function">(<span class="hljs-params">list1, list2</span>) =&gt;</span>
  list1.reduce(<span class="hljs-function">(<span class="hljs-params">acc, list1Item</span>) =&gt;</span> {
    list2.forEach(<span class="hljs-function">(<span class="hljs-params">list2Item</span>) =&gt;</span> {
      acc.push([list1Item, list2Item]);
    });

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h2 id="heading-want-free-coaching">Want Free Coaching?</h2>
<p>If you'd like to schedule a free call to discuss Front-End development questions regarding code, interviews, career, or anything else <a target="_blank" href="https://twitter.com/yazeedBee">follow me on Twitter and DM me</a>.</p>
<p>After that if you enjoy our first meeting, we can discuss an ongoing coaching to help you reach your Front-End development goals!</p>
<h2 id="heading-thanks-for-reading">Thanks for reading</h2>
<p>For more content like this, check out <a href="https://yazeedb.com">https://yazeedb.com!</a></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 10 More Utility Functions Made with Reduce ]]>
                </title>
                <description>
                    <![CDATA[ By Yazeed Bzadough This time, with a test suite! Previously I wrote about 10 utility functions implemented with JavaScript's reduce function. It was well-received, and I walked away with an even deeper appreciation for this magnificent multi-tool. Wh... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/10-more-js-utils-using-reduce/</link>
                <guid isPermaLink="false">66d46173a326133d12440a98</guid>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ramda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 05 Nov 2019 12:59:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/cover-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yazeed Bzadough</p>
<p>This time, with a test suite!</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/10-js-util-functions-in-reduce/">Previously</a> I wrote about 10 utility functions implemented with JavaScript's <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">reduce function</a>. It was well-received, and I walked away with an even deeper appreciation for this magnificent multi-tool. Why not try 10 more?</p>
<p>Many of these were inspired by the awesome libraries <a target="_blank" href="https://lodash.com/">Lodash</a> and <a target="_blank" href="https://ramdajs.com/">Ramda</a>! I also wrote unit tests to ensure correct behavior. You can see everything on the <a target="_blank" href="https://github.com/yazeedb/js-utils-using-reduce">Github repo here</a>.</p>
<h2 id="heading-1-pipe">1. pipe</h2>
<h3 id="heading-parameters">Parameters</h3>
<ol>
<li><code>...functions</code> - Any number of functions.</li>
</ol>
<h3 id="heading-description">Description</h3>
<p>Performs <em>left-to-right</em> function composition. The first argument to a pipeline acts as the initial value, and is transformed as it passes through each function.</p>
<h3 id="heading-implementation">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> pipe = <span class="hljs-function">(<span class="hljs-params">...functions</span>) =&gt;</span> <span class="hljs-function">(<span class="hljs-params">initialValue</span>) =&gt;</span>
  functions.reduce(<span class="hljs-function">(<span class="hljs-params">value, fn</span>) =&gt;</span> fn(value), initialValue);
</code></pre>
<h3 id="heading-usage">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> mathSequence = pipe(
    <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">2</span>,
    <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x - <span class="hljs-number">1</span>,
    <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">3</span>
  );

mathSequence(<span class="hljs-number">1</span>); <span class="hljs-comment">// 3</span>
mathSequence(<span class="hljs-number">2</span>); <span class="hljs-comment">// 9</span>
mathSequence(<span class="hljs-number">3</span>); <span class="hljs-comment">// 15</span>
</code></pre>
<p>For more detail, I wrote an <a target="_blank" href="https://www.yazeedb.com/posts/a-quick-intro-to-pipe-and-compose">article on pipe here</a>.</p>
<h2 id="heading-2-compose">2. compose</h2>
<h3 id="heading-parameters-1">Parameters</h3>
<ol>
<li><code>...functions</code> - Any number of functions.</li>
</ol>
<h3 id="heading-description-1">Description</h3>
<p>Performs <em>right-to-left</em> function composition. The first argument to a pipeline acts as the initial value, and is transformed as it passes through each function.</p>
<p>Works like <code>pipe</code>, but in the opposite direction.</p>
<h3 id="heading-implementation-1">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> compose = <span class="hljs-function">(<span class="hljs-params">...functions</span>) =&gt;</span> <span class="hljs-function">(<span class="hljs-params">initialValue</span>) =&gt;</span>
  functions.reduceRight(<span class="hljs-function">(<span class="hljs-params">value, fn</span>) =&gt;</span> fn(value), initialValue);
</code></pre>
<h3 id="heading-usage-1">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> mathSequence = compose(
    <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">2</span>,
    <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x - <span class="hljs-number">1</span>,
    <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">3</span>
  );

mathSequence(<span class="hljs-number">1</span>); <span class="hljs-comment">// 4</span>
mathSequence(<span class="hljs-number">2</span>); <span class="hljs-comment">// 10</span>
mathSequence(<span class="hljs-number">3</span>); <span class="hljs-comment">// 16</span>
</code></pre>
<p>For more detail, I wrote an <a target="_blank" href="https://www.yazeedb.com/posts/a-quick-intro-to-pipe-and-compose">article on compose here</a>.</p>
<h2 id="heading-3-zip">3. zip</h2>
<h3 id="heading-parameters-2">Parameters</h3>
<ol>
<li><code>list1</code> - List of items.</li>
<li><code>list2</code> - List of items.</li>
</ol>
<h3 id="heading-description-2">Description</h3>
<p>Pairs items from two lists via index. If list lengths are not equal, the shorter list's length is used.</p>
<h3 id="heading-implementation-2">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> zip = <span class="hljs-function">(<span class="hljs-params">list1, list2</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> sourceList = list1.length &gt; list2.length ? list2 : list1;

  <span class="hljs-keyword">return</span> sourceList.reduce(<span class="hljs-function">(<span class="hljs-params">acc, _, index</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> value1 = list1[index];
    <span class="hljs-keyword">const</span> value2 = list2[index];

    acc.push([value1, value2]);

    <span class="hljs-keyword">return</span> acc;
  }, []);
};
</code></pre>
<h3 id="heading-usage-2">Usage</h3>
<pre><code class="lang-js">zip([<span class="hljs-number">1</span>, <span class="hljs-number">3</span>], [<span class="hljs-number">2</span>, <span class="hljs-number">4</span>]); <span class="hljs-comment">// [[1, 2], [3, 4]]</span>

zip([<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>], [<span class="hljs-number">2</span>, <span class="hljs-number">4</span>]); <span class="hljs-comment">// [[1, 2], [3, 4]]</span>

zip([<span class="hljs-number">1</span>, <span class="hljs-number">3</span>], [<span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]); <span class="hljs-comment">// [[1, 2], [3, 4]]</span>

zip([<span class="hljs-string">'Decode'</span>, <span class="hljs-string">'secret'</span>], [<span class="hljs-string">'this'</span>, <span class="hljs-string">'message!'</span>]);
<span class="hljs-comment">// [['Decode', 'this'], ['secret', 'message!']]</span>
</code></pre>
<h2 id="heading-4-intersperse">4. intersperse</h2>
<h3 id="heading-parameters-3">Parameters</h3>
<ol>
<li><code>separator</code> - Item to insert.</li>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-3">Description</h3>
<p>Inserts a separator between each element of a list.</p>
<h3 id="heading-implementation-3">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> intersperse = <span class="hljs-function">(<span class="hljs-params">separator, list</span>) =&gt;</span>
  list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value, index</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (index === list.length - <span class="hljs-number">1</span>) {
      acc.push(value);
    } <span class="hljs-keyword">else</span> {
      acc.push(value, separator);
    }

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h3 id="heading-usage-3">Usage</h3>
<pre><code class="lang-js">intersperse(<span class="hljs-string">'Batman'</span>, [<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-comment">// [1, 'Batman', 2, 'Batman', 3, 'Batman', 4, 'Batman', 5, 'Batman', 6]</span>

intersperse(<span class="hljs-string">'Batman'</span>, []);
<span class="hljs-comment">// []</span>
</code></pre>
<h2 id="heading-5-insert">5. insert</h2>
<h3 id="heading-parameters-4">Parameters</h3>
<ol>
<li><code>index</code> - Index to insert element at.</li>
<li><code>newItem</code> - Element to insert.</li>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-4">Description</h3>
<p>Inserts an element at the given index. If the index is too large, element is inserted at the end of the list.</p>
<h3 id="heading-implementation-4">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> insert = <span class="hljs-function">(<span class="hljs-params">index, newItem, list</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (index &gt; list.length - <span class="hljs-number">1</span>) {
    <span class="hljs-keyword">return</span> [...list, newItem];
  }

  <span class="hljs-keyword">return</span> list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value, sourceArrayIndex</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (index === sourceArrayIndex) {
      acc.push(newItem, value);
    } <span class="hljs-keyword">else</span> {
      acc.push(value);
    }

    <span class="hljs-keyword">return</span> acc;
  }, []);
};
</code></pre>
<h3 id="heading-usage-4">Usage</h3>
<pre><code class="lang-js">insert(<span class="hljs-number">0</span>, <span class="hljs-string">'Batman'</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// ['Batman', 1, 2, 3]</span>

insert(<span class="hljs-number">1</span>, <span class="hljs-string">'Batman'</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [1, 'Batman', 2, 3]</span>

insert(<span class="hljs-number">2</span>, [<span class="hljs-string">'Batman'</span>], [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [1, 2, ['Batman'], 3]</span>

insert(<span class="hljs-number">10</span>, [<span class="hljs-string">'Batman'</span>], [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [1, 2, 3, ['Batman']]</span>
</code></pre>
<h2 id="heading-6-flatten">6. flatten</h2>
<h3 id="heading-parameters-5">Parameters</h3>
<ol>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-5">Description</h3>
<p>Flattens a list of items by one level.</p>
<h3 id="heading-implementation-5">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> flatten = <span class="hljs-function">(<span class="hljs-params">list</span>) =&gt;</span> list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value</span>) =&gt;</span> acc.concat(value), []);
</code></pre>
<h3 id="heading-usage-5">Usage</h3>
<pre><code class="lang-js">flatten([[<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-comment">// [1, 2, 3, 4]</span>

flatten([[<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-comment">// [1, 2, [3, 4]]</span>

flatten([[[<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-comment">// [[1, 2], 3, 4]</span>

flatten([[[<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-comment">// [[1, 2], [3, 4]]</span>
</code></pre>
<h2 id="heading-7-flatmap">7. flatMap</h2>
<h3 id="heading-parameters-6">Parameters</h3>
<ol>
<li><code>mappingFunction</code> - Function to run on each list item.</li>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-6">Description</h3>
<p>Maps each list item according to the given function, then flattens the result.</p>
<h3 id="heading-implementation-6">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-comment">// Kind of cheating, because we already implemented flatten ?</span>
<span class="hljs-keyword">const</span> flatMap = <span class="hljs-function">(<span class="hljs-params">mappingFunction, list</span>) =&gt;</span> flatten(list.map(mappingFunction));
</code></pre>
<h3 id="heading-usage-6">Usage</h3>
<pre><code class="lang-js">flatMap(<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-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]);
<span class="hljs-comment">// [2, 4, 6, 8]</span>

flatMap(<span class="hljs-function">(<span class="hljs-params">n</span>) =&gt;</span> [n, n], [<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-comment">// [1, 1, 2, 2, 3, 3, 4, 4]</span>

flatMap(<span class="hljs-function">(<span class="hljs-params">s</span>) =&gt;</span> s.split(<span class="hljs-string">' '</span>), [<span class="hljs-string">'flatMap'</span>, <span class="hljs-string">'should be'</span>, <span class="hljs-string">'mapFlat'</span>]);
<span class="hljs-comment">// ['flatMap', 'should', 'be', 'mapFlat']</span>
</code></pre>
<h2 id="heading-8-includes">8. includes</h2>
<h3 id="heading-parameters-7">Parameters</h3>
<ol>
<li><code>item</code> - Item to check the list for.</li>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-7">Description</h3>
<p>Checks a list for a given element. If the element is found, returns <code>true</code>. Otherwise returns <code>false</code>.</p>
<h3 id="heading-implementation-7">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> includes = <span class="hljs-function">(<span class="hljs-params">item, list</span>) =&gt;</span>
  list.reduce(<span class="hljs-function">(<span class="hljs-params">isIncluded, value</span>) =&gt;</span> isIncluded || item === value, <span class="hljs-literal">false</span>);
</code></pre>
<h3 id="heading-usage-7">Usage</h3>
<pre><code class="lang-js">includes(<span class="hljs-number">3</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// true</span>
includes(<span class="hljs-number">3</span>, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>]); <span class="hljs-comment">// false</span>
includes(<span class="hljs-number">0</span>, []); <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="heading-9-compact">9. compact</h2>
<h3 id="heading-parameters-8">Parameters</h3>
<ol>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-8">Description</h3>
<p>Removes "falsey" values from a list.</p>
<h3 id="heading-implementation-8">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> compact = <span class="hljs-function">(<span class="hljs-params">list</span>) =&gt;</span>
  list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (value) {
      acc.push(value);
    }

    <span class="hljs-keyword">return</span> acc;
  }, []);
</code></pre>
<h3 id="heading-usage-8">Usage</h3>
<pre><code class="lang-js">compact([<span class="hljs-number">0</span>, <span class="hljs-literal">null</span>, <span class="hljs-number">1</span>, <span class="hljs-literal">undefined</span>, <span class="hljs-number">2</span>, <span class="hljs-string">''</span>, <span class="hljs-number">3</span>, <span class="hljs-literal">false</span>, <span class="hljs-number">4</span>, <span class="hljs-literal">NaN</span>]);
<span class="hljs-comment">// [1, 2, 3, 4]</span>
</code></pre>
<h2 id="heading-10-arrayintoobject">10. arrayIntoObject</h2>
<h3 id="heading-parameters-9">Parameters</h3>
<ol>
<li><code>key</code> - String to use as the new object key.</li>
<li><code>list</code> - List of items.</li>
</ol>
<h3 id="heading-description-9">Description</h3>
<p>Converts an array into an object, using the given key as the new object's key.</p>
<h3 id="heading-implementation-9">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> arrayIntoObject = <span class="hljs-function">(<span class="hljs-params">key, list</span>) =&gt;</span>
  list.reduce(<span class="hljs-function">(<span class="hljs-params">acc, obj</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> value = obj[key];

    acc[value] = obj;

    <span class="hljs-keyword">return</span> acc;
  }, {});
</code></pre>
<h3 id="heading-usage-9">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> users = [
    { <span class="hljs-attr">username</span>: <span class="hljs-string">'JX01'</span>, <span class="hljs-attr">status</span>: <span class="hljs-string">'offline'</span> },
    { <span class="hljs-attr">username</span>: <span class="hljs-string">'yazeedBee'</span>, <span class="hljs-attr">status</span>: <span class="hljs-string">'online'</span> }
];

arrayIntoObject(<span class="hljs-string">'username'</span>, users);
<span class="hljs-comment">/*
{
  JX01: {
    username: 'JX01',
    status: 'offline'
  },
  yazeedBee: { username: 'yazeedBee', status: 'online' }
}
*/</span>

arrayIntoObject(<span class="hljs-string">'status'</span>, users);
<span class="hljs-comment">/*
{
  offline: {
    username: 'JX01',
    status: 'offline'
  },
  online: { username: 'yazeedBee', status: 'online' }
}
*/</span>
</code></pre>
<h2 id="heading-want-free-coaching">Want Free Coaching?</h2>
<p>If you'd like to schedule a free call to discuss Front-End development questions regarding code, interviews, career, or anything else <a target="_blank" href="https://twitter.com/yazeedBee">follow me on Twitter and DM me</a>.</p>
<p>After that if you enjoy our first meeting, we can discuss an ongoing coaching to help you reach your Front-End development goals!</p>
<h2 id="heading-thanks-for-reading">Thanks for reading</h2>
<p>For more content like this, check out <a href="https://yazeedb.com">https://yazeedb.com!</a></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 10 JavaScript Utility Functions Made with Reduce ]]>
                </title>
                <description>
                    <![CDATA[ By Yazeed Bzadough The multi-tool strikes again. In my last article I offered you a challenge to recreate well-known functions using reduce. This article will show you how some of them can be implemented, along with some extras! In total we're going ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/10-js-util-functions-in-reduce/</link>
                <guid isPermaLink="false">66d461712472e5ed2fa07bbf</guid>
                
                    <category>
                        <![CDATA[ arrays ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ramda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 17 Oct 2019 12:59:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/10-js-utility-functions-using-reduce-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yazeed Bzadough</p>
<p>The multi-tool strikes again.</p>
<p>In <a target="_blank" href="https://www.yazeedb.com/posts/learn-reduce-in-10-minutes/">my last article</a> I offered you a challenge to recreate well-known functions using <code>reduce</code>. This article will show you how some of them can be implemented, along with some extras!</p>
<p>In total we're going to look at ten utility functions. They're incredibly handy on your projects, and best of all, they're implemented using <code>reduce</code>! I drew lots of inspiration from the <a target="_blank" href="https://ramdajs.com/">RamdaJS library</a> for this one, so check that out!</p>
<h2 id="heading-1-some">1. some</h2>
<h3 id="heading-parameters">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items to test.</li>
</ol>
<h3 id="heading-description">Description</h3>
<p>If <code>predicate</code> returns <code>true</code> for <em>any</em> item, <code>some</code> returns <code>true</code>. Otherwise it returns <code>false</code>.</p>
<h3 id="heading-implementation">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> some = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value</span>) =&gt;</span> acc || predicate(value), <span class="hljs-literal">false</span>);
</code></pre>
<h3 id="heading-usage">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> equals3 = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x === <span class="hljs-number">3</span>;

some(equals3, [<span class="hljs-number">3</span>]); <span class="hljs-comment">// true</span>
some(equals3, [<span class="hljs-number">3</span>, <span class="hljs-number">3</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// true</span>
some(equals3, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// true</span>
some(equals3, [<span class="hljs-number">2</span>]); <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="heading-2-all">2. all</h2>
<h3 id="heading-parameters-1">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items to test.</li>
</ol>
<h3 id="heading-description-1">Description</h3>
<p>If <code>predicate</code> returns <code>true</code> for <em>every</em> item, <code>all</code> returns <code>true</code>. Otherwise it returns <code>false</code>.</p>
<h3 id="heading-implementation-1">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> all = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value</span>) =&gt;</span> acc &amp;&amp; predicate(value), <span class="hljs-literal">true</span>);
</code></pre>
<h3 id="heading-usage-1">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> equals3 = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x === <span class="hljs-number">3</span>;

all(equals3, [<span class="hljs-number">3</span>]); <span class="hljs-comment">// true</span>
all(equals3, [<span class="hljs-number">3</span>, <span class="hljs-number">3</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// true</span>
all(equals3, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// false</span>
all(equals3, [<span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]; <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="heading-3-none">3. none</h2>
<h3 id="heading-parameters-2">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items to test.</li>
</ol>
<h3 id="heading-description-2">Description</h3>
<p>If <code>predicate</code> returns <code>false</code> for <em>every</em> item, <code>none</code> returns <code>true</code>. Otherwise it returns <code>false</code>.</p>
<h3 id="heading-implementation-2">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> none = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">acc, value</span>) =&gt;</span> !acc &amp;&amp; !predicate(value), <span class="hljs-literal">false</span>);
</code></pre>
<h3 id="heading-usage-2">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isEven = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>;

none(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>]); <span class="hljs-comment">// true</span>
none(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]); <span class="hljs-comment">// false</span>
none(equals3, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>]); <span class="hljs-comment">// true</span>
none(equals3, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="heading-4-map">4. map</h2>
<h3 id="heading-parameters-3">Parameters</h3>
<ol>
<li><code>transformFunction</code> - Function to run on each element.</li>
<li><code>array</code> - List of items to transform.</li>
</ol>
<h3 id="heading-description-3">Description</h3>
<p>Returns a new array of items, each one transformed according to the given <code>transformFunction</code>.</p>
<h3 id="heading-implementation-3">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> map = <span class="hljs-function">(<span class="hljs-params">transformFunction, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">newArray, item</span>) =&gt;</span> {
    newArray.push(transformFunction(item));

    <span class="hljs-keyword">return</span> newArray;
  }, []);
</code></pre>
<h3 id="heading-usage-3">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> double = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x * <span class="hljs-number">2</span>;
<span class="hljs-keyword">const</span> reverseString = <span class="hljs-function">(<span class="hljs-params">string</span>) =&gt;</span>
  string
    .split(<span class="hljs-string">''</span>)
    .reverse()
    .join(<span class="hljs-string">''</span>);

map(double, [<span class="hljs-number">100</span>, <span class="hljs-number">200</span>, <span class="hljs-number">300</span>]);
<span class="hljs-comment">// [200, 400, 600]</span>

map(reverseString, [<span class="hljs-string">'Hello World'</span>, <span class="hljs-string">'I love map'</span>]);
<span class="hljs-comment">// ['dlroW olleH', 'pam evol I']</span>
</code></pre>
<h2 id="heading-5-filter">5. filter</h2>
<h3 id="heading-parameters-4">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items to filter.</li>
</ol>
<h3 id="heading-description-4">Description</h3>
<p>Returns a new array. If <code>predicate</code> returns <code>true</code>, that item is added to the new array. Otherwise that item is excluded from the new array.</p>
<h3 id="heading-implementation-4">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> filter = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">newArray, item</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (predicate(item) === <span class="hljs-literal">true</span>) {
      newArray.push(item);
    }

    <span class="hljs-keyword">return</span> newArray;
  }, []);
</code></pre>
<h3 id="heading-usage-4">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isEven = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>;

filter(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [2]</span>

filter(equals3, [<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">3</span>]);
<span class="hljs-comment">// [3, 3]</span>
</code></pre>
<h2 id="heading-6-reject">6. reject</h2>
<h3 id="heading-parameters-5">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items to filter.</li>
</ol>
<h3 id="heading-description-5">Description</h3>
<p>Just like <code>filter</code>, but with the opposite behavior.</p>
<p>If <code>predicate</code> returns <code>false</code>, that item is added to the new array. Otherwise that item is excluded from the new array.</p>
<h3 id="heading-implementation-5">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> reject = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">newArray, item</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (predicate(item) === <span class="hljs-literal">false</span>) {
      newArray.push(item);
    }

    <span class="hljs-keyword">return</span> newArray;
  }, []);
</code></pre>
<h3 id="heading-usage-5">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isEven = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>;

reject(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [1, 3]</span>

reject(equals3, [<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">3</span>]);
<span class="hljs-comment">// [1, 2, 4]</span>
</code></pre>
<h2 id="heading-7-find">7. find</h2>
<h3 id="heading-parameters-6">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items to search.</li>
</ol>
<h3 id="heading-description-6">Description</h3>
<p>Returns the first element that matches the given <code>predicate</code>. If no element matches then <code>undefined</code> is returned.</p>
<h3 id="heading-implementation-6">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> find = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">result, item</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (result !== <span class="hljs-literal">undefined</span>) {
      <span class="hljs-keyword">return</span> result;
    }

    <span class="hljs-keyword">if</span> (predicate(item) === <span class="hljs-literal">true</span>) {
      <span class="hljs-keyword">return</span> item;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-literal">undefined</span>;
  }, <span class="hljs-literal">undefined</span>);
</code></pre>
<h3 id="heading-usage-6">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isEven = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>;

find(isEven, []); <span class="hljs-comment">// undefined</span>
find(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]); <span class="hljs-comment">// 2</span>
find(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>]); <span class="hljs-comment">// undefined</span>
find(equals3, [<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">3</span>]); <span class="hljs-comment">// 3</span>
find(equals3, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>]); <span class="hljs-comment">// undefined</span>
</code></pre>
<h2 id="heading-8-partition">8. partition</h2>
<h3 id="heading-parameters-7">Parameters</h3>
<ol>
<li><code>predicate</code> - Function that returns <code>true</code> or <code>false</code>.</li>
<li><code>array</code> - List of items.</li>
</ol>
<h3 id="heading-description-7">Description</h3>
<p>"Partitions" or splits an array into two based on the <code>predicate</code>. If <code>predicate</code> returns <code>true</code>, the item goes into list 1. Otherwise the item goes into list 2.</p>
<h3 id="heading-implementation-7">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> partition = <span class="hljs-function">(<span class="hljs-params">predicate, array</span>) =&gt;</span>
  array.reduce(
    <span class="hljs-function">(<span class="hljs-params">result, item</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> [list1, list2] = result;

      <span class="hljs-keyword">if</span> (predicate(item) === <span class="hljs-literal">true</span>) {
        list1.push(item);
      } <span class="hljs-keyword">else</span> {
        list2.push(item);
      }

      <span class="hljs-keyword">return</span> result;
    },
    [[], []]
  );
</code></pre>
<h3 id="heading-usage-7">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> isEven = <span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>;

partition(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
<span class="hljs-comment">// [[2], [1, 3]]</span>

partition(isEven, [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>]);
<span class="hljs-comment">// [[], [1, 3, 5]]</span>

partition(equals3, [<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">3</span>]);
<span class="hljs-comment">// [[3, 3], [1, 2, 4]]</span>

partition(equals3, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>]);
<span class="hljs-comment">// [[], [1, 2, 4]]</span>
</code></pre>
<h2 id="heading-9-pluck">9. pluck</h2>
<h3 id="heading-parameters-8">Parameters</h3>
<ol>
<li><code>key</code> - Key name to pluck from the object</li>
<li><code>array</code> - List of items.</li>
</ol>
<h3 id="heading-description-8">Description</h3>
<p>Plucks the given <code>key</code> off of each item in the array. Returns a new array of these values.</p>
<h3 id="heading-implementation-8">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> pluck = <span class="hljs-function">(<span class="hljs-params">key, array</span>) =&gt;</span>
  array.reduce(<span class="hljs-function">(<span class="hljs-params">values, current</span>) =&gt;</span> {
    values.push(current[key]);

    <span class="hljs-keyword">return</span> values;
  }, []);
</code></pre>
<h3 id="heading-usage-8">Usage</h3>
<pre><code class="lang-js">pluck(<span class="hljs-string">'name'</span>, [{ <span class="hljs-attr">name</span>: <span class="hljs-string">'Batman'</span> }, { <span class="hljs-attr">name</span>: <span class="hljs-string">'Robin'</span> }, { <span class="hljs-attr">name</span>: <span class="hljs-string">'Joker'</span> }]);
<span class="hljs-comment">// ['Batman', 'Robin', 'Joker']</span>

pluck(<span class="hljs-number">0</span>, [[<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-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>]]);
<span class="hljs-comment">// [1, 4, 7]</span>
</code></pre>
<h2 id="heading-10-scan">10. scan</h2>
<h3 id="heading-parameters-9">Parameters</h3>
<ol>
<li><code>reducer</code> - Standard reducer function that receives two parameters - the accumulator and current element from the array.</li>
<li><code>initialValue</code> - The initial value for the accumulator.</li>
<li><code>array</code> - List of items.</li>
</ol>
<h3 id="heading-description-9">Description</h3>
<p>Works just like <code>reduce</code> but instead just the single result, it returns a list of every reduced value on the way to the single result.</p>
<h3 id="heading-implementation-9">Implementation</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> scan = <span class="hljs-function">(<span class="hljs-params">reducer, initialValue, array</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> reducedValues = [];

  array.reduce(<span class="hljs-function">(<span class="hljs-params">acc, current</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> newAcc = reducer(acc, current);

    reducedValues.push(newAcc);

    <span class="hljs-keyword">return</span> newAcc;
  }, initialValue);

  <span class="hljs-keyword">return</span> reducedValues;
};
</code></pre>
<h3 id="heading-usage-9">Usage</h3>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> add = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> x + y;
<span class="hljs-keyword">const</span> multiply = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> x * y;

scan(add, <span class="hljs-number">0</span>, [<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-comment">// [1, 3, 6, 10, 15, 21] - Every number added from 1-6</span>

scan(multiply, <span class="hljs-number">1</span>, [<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-comment">// [1, 2, 6, 24, 120, 720] - Every number multiplied from 1-6</span>
</code></pre>
<h2 id="heading-want-free-coaching">Want Free Coaching?</h2>
<p>If you'd like to schedule a free call to discuss Front-End development questions regarding code, interviews, career, or anything else <a target="_blank" href="https://twitter.com/yazeedBee">follow me on Twitter and DM me</a>.</p>
<p>After that if you enjoy our first meeting, we can discuss an ongoing coaching to help you reach your Front-End development goals!</p>
<h2 id="heading-thanks-for-reading">Thanks for reading</h2>
<p>For more content like this, check out <a href="https://yazeedb.com">https://yazeedb.com!</a></p>
<p>Until next time!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Deeply Understand Currying in 7 Minutes ]]>
                </title>
                <description>
                    <![CDATA[ By Yazeed Bzadough Eric Elliott’s exceptional Composing Software series is initially what got me excited about functional programming. It's a must-read. At one point in the series, he mentioned currying. Both computer science and mathematics agree on... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/deeply-understand-currying-in-7-minutes/</link>
                <guid isPermaLink="false">66d4618573634435aafcf000</guid>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ramda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 05 Jul 2019 11:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/07/snape-currying-in-7-minutes.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yazeed Bzadough</p>
<p>Eric Elliott’s exceptional <a target="_blank" href="https://medium.com/javascript-scene/the-rise-and-fall-and-rise-of-functional-programming-composable-software-c2d91b424c8c">Composing Software</a> series is initially what got me excited about functional programming. It's a must-read.</p>
<p>At one point in the series, he mentioned <em>currying</em>. Both computer science and mathematics agree on the definition:</p>
<blockquote>
<p>Currying turns multi-argument functions into unary (single argument) functions.</p>
</blockquote>
<p>Curried functions take many arguments <strong>one at a time</strong>. So if you have</p>
<pre><code class="lang-js">greet = <span class="hljs-function">(<span class="hljs-params">greeting, first, last</span>) =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${greeting}</span>, <span class="hljs-subst">${first}</span> <span class="hljs-subst">${last}</span>`</span>;

greet(<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'Bruce'</span>, <span class="hljs-string">'Wayne'</span>); <span class="hljs-comment">// Hello, Bruce Wayne</span>
</code></pre>
<p>Properly currying <code>greet</code> gives you</p>
<pre><code class="lang-js">curriedGreet = curry(greet);

curriedGreet(<span class="hljs-string">'Hello'</span>)(<span class="hljs-string">'Bruce'</span>)(<span class="hljs-string">'Wayne'</span>); <span class="hljs-comment">// Hello, Bruce Wayne</span>
</code></pre>
<p>This 3-argument function has been turned into three unary functions. As you supply one parameter, a new function pops out expecting the next one.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/07/dog-properly-currying-a-function-1.jpeg" alt="dog-properly-currying-a-function-1" width="600" height="400" loading="lazy"></p>
<h2 id="heading-properly">Properly?</h2>
<p>I say "properly currying" because some <code>curry</code> functions are more flexible in their usage. Currying's great in theory, but invoking a function for each argument gets tiring in JavaScript.</p>
<p><a target="_blank" href="https://ramdajs.com/">Ramda's</a> <code>curry</code> function lets you invoke <code>curriedGreet</code> like this:</p>
<pre><code class="lang-js"><span class="hljs-comment">// greet requires 3 params: (greeting, first, last)</span>

<span class="hljs-comment">// these all return a function looking for (first, last)</span>
curriedGreet(<span class="hljs-string">'Hello'</span>);
curriedGreet(<span class="hljs-string">'Hello'</span>)();
curriedGreet()(<span class="hljs-string">'Hello'</span>)()();

<span class="hljs-comment">// these all return a function looking for (last)</span>
curriedGreet(<span class="hljs-string">'Hello'</span>)(<span class="hljs-string">'Bruce'</span>);
curriedGreet(<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'Bruce'</span>);
curriedGreet(<span class="hljs-string">'Hello'</span>)()(<span class="hljs-string">'Bruce'</span>)();

<span class="hljs-comment">// these return a greeting, since all 3 params were honored</span>
curriedGreet(<span class="hljs-string">'Hello'</span>)(<span class="hljs-string">'Bruce'</span>)(<span class="hljs-string">'Wayne'</span>);
curriedGreet(<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'Bruce'</span>, <span class="hljs-string">'Wayne'</span>);
curriedGreet(<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'Bruce'</span>)()()(<span class="hljs-string">'Wayne'</span>);
</code></pre>
<p>Notice you can choose to give multiple arguments in a single shot. This implementation's more useful while writing code.</p>
<p>And as demonstrated above, you can invoke this function forever without parameters and it’ll always return a function that expects the remaining parameters.</p>
<h2 id="heading-hows-this-possible">How's This Possible?</h2>
<p>Mr. Elliot shared a <code>curry</code> implementation much like Ramda's. Here’s the code, or as he aptly called it, a magic spell:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> curry = <span class="hljs-function">(<span class="hljs-params">f, arr = []</span>) =&gt;</span> <span class="hljs-function">(<span class="hljs-params">...args</span>) =&gt;</span>
  (<span class="hljs-function">(<span class="hljs-params">a</span>) =&gt;</span> (a.length === f.length ? f(...a) : curry(f, a)))([...arr, ...args]);
</code></pre>
<h2 id="heading-umm">Umm… ?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/07/that-code-is-hard-to-read-cmm.jpeg" alt="that-code-is-hard-to-read-cmm" width="600" height="400" loading="lazy"></p>
<p>Yeah, I know... It's incredibly concise, so let's refactor and appreciate it together.</p>
<h2 id="heading-this-version-works-the-same">This Version Works the Same</h2>
<p>I've also sprinkled <code>debugger</code> statements to examine it in Chrome Developer Tools.</p>
<pre><code class="lang-js">curry = <span class="hljs-function">(<span class="hljs-params">originalFunction, initialParams = []</span>) =&gt;</span> {
  <span class="hljs-keyword">debugger</span>;

  <span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">...nextParams</span>) =&gt;</span> {
    <span class="hljs-keyword">debugger</span>;

    <span class="hljs-keyword">const</span> curriedFunction = <span class="hljs-function">(<span class="hljs-params">params</span>) =&gt;</span> {
      <span class="hljs-keyword">debugger</span>;

      <span class="hljs-keyword">if</span> (params.length === originalFunction.length) {
        <span class="hljs-keyword">return</span> originalFunction(...params);
      }

      <span class="hljs-keyword">return</span> curry(originalFunction, params);
    };

    <span class="hljs-keyword">return</span> curriedFunction([...initialParams, ...nextParams]);
  };
};
</code></pre>
<p>Open your <a target="_blank" href="https://developers.google.com/web/tools/chrome-devtools/">Developer Tools</a> and follow along!</p>
<h2 id="heading-lets-do-this">Let's Do This!</h2>
<p>Paste <code>greet</code> and <code>curry</code> into your console. Then enter <code>curriedGreet = curry(greet)</code> and begin the madness.</p>
<h3 id="heading-pause-on-line-2">Pause on line 2</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*8_q3YkOu6fDzIEMY65lqUg.png" alt="1*8_q3YkOu6fDzIEMY65lqUg" width="1600" height="893" loading="lazy"></p>
<p>Inspecting our two params we see <code>originalFunction</code> is <code>greet</code> and <code>initialParams</code> defaulted to an empty array because we didn’t supply it. Move to the next breakpoint and, oh wait… that’s it.</p>
<p>Yep! <code>curry(greet)</code> just returns a new function that expects 3 more parameters. Type <code>curriedGreet</code> in the console to see what I’m talking about.</p>
<p>When you’re done playing with that, let’s get a bit crazier and do
<code>sayHello = curriedGreet('Hello')</code>.</p>
<h3 id="heading-pause-on-line-4">Pause on line 4</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*FXCJQi5Numlbis5d_bGsjw.png" alt="1*FXCJQi5Numlbis5d_bGsjw" width="1600" height="894" loading="lazy"></p>
<p>Before moving on, type <code>originalFunction</code> and <code>initialParams</code> in your console. Notice we can still access those 2 parameters even though we’re in a completely new function? That’s because functions returned from parent functions enjoy their parent’s scope.</p>
<h4 id="heading-real-life-inheritance">Real-life inheritance</h4>
<p>After a parent function passes on, they leave their parameters for their kids to use. Kind of like inheritance in the real life sense.</p>
<p><code>curry</code> was initially given <code>originalFunction</code> and <code>initialParams</code> and then returned a “child” function. Those 2 variables weren’t <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management">disposed of</a> yet because maybe that child needs them. If he doesn’t, <em>then</em> that scope gets cleaned up because when no one references you, that’s when you truly die.</p>
<h3 id="heading-ok-back-to-line-4">Ok, back to line 4…</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_TFVnxtqgisi1i0q_K3dUQ.png" alt="1*_TFVnxtqgisi1i0q_K3dUQ" width="1600" height="883" loading="lazy"></p>
<p>Inspect <code>nextParams</code> and see that it’s <code>['Hello']</code>…an array? But I thought we said <code>curriedGreet(‘Hello’)</code> , not <code>curriedGreet(['Hello'])</code>!</p>
<p>Correct: we invoked <code>curriedGreet</code> with <code>'Hello'</code>, but thanks to the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Rest_syntax_%28parameters%29">rest syntax</a>, we’ve <em>turned</em> <code>'Hello'</code> into <code>['Hello']</code>.</p>
<h3 id="heading-y-tho">Y THO?!</h3>
<p><code>curry</code> is a general function that can be supplied 1, 10, or 10,000,000 parameters, so it needs a way to reference all of them. Using the rest syntax like that captures every single parameter in one array, making <code>curry</code>'s job much easier.</p>
<p>Let’s jump to the next <code>debugger</code> statement.</p>
<h3 id="heading-line-6-now-but-hold-on">Line 6 now, but hold on.</h3>
<p>You may have noticed that line 12 actually ran before the <code>debugger</code> statement on line 6. If not, look closer. Our program defines a function called <code>curriedFunction</code> on line 5, uses it on line 12, and <em>then</em> we hit that <code>debugger</code> statement on line 6. And what’s <code>curriedFunction</code> invoked with?</p>
<pre><code class="lang-js">[...initialParams, ...nextParams];
</code></pre>
<p>Yuuuup. Look at <code>params</code> on line 5 and you’ll see <code>['Hello']</code>. Both <code>initialParams</code> and <code>nextParams</code> were arrays, so we flattened and combined them into a single array using the handy <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Syntax">spread operator</a>.</p>
<p>Here’s where the good stuff happens.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*pM31i2QVNxVUiqj9aZzVvg.png" alt="1*pM31i2QVNxVUiqj9aZzVvg" width="1600" height="886" loading="lazy"></p>
<p>Line 7 says “If <code>params</code> and <code>originalFunction</code> are the same length, call <code>greet</code> with our params and we’re done.” Which reminds me…</p>
<h3 id="heading-javascript-functions-have-lengths-too">JavaScript functions have lengths too</h3>
<p>This is how <code>curry</code> does its magic! This is how it decides whether or not to ask for more parameters.</p>
<p>In JavaScript, a function’s <code>.length</code> property tells you <em>how many arguments it expects</em>.</p>
<pre><code class="lang-js">greet.length; <span class="hljs-comment">// 3</span>

iTakeOneParam = <span class="hljs-function">(<span class="hljs-params">a</span>) =&gt;</span> {};
iTakeTwoParams = <span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> {};

iTakeOneParam.length; <span class="hljs-comment">// 1</span>
iTakeTwoParams.length; <span class="hljs-comment">// 2</span>
</code></pre>
<p>If our provided and expected parameters match, we’re good, just hand them off to the original function and finish the job!</p>
<h3 id="heading-thats-baller">That’s baller ?</h3>
<p>But in our case, the parameters and function length are <em>not</em> the same. We only provided <code>‘Hello’</code>, so <code>params.length</code> is 1, and <code>originalFunction.length</code> is 3 because <code>greet</code> expects 3 parameters: <code>greeting, first, last</code>.</p>
<h3 id="heading-so-what-happens-next">So what happens next?</h3>
<p>Well since that <code>if</code> statement evaluates to <code>false</code>, the code will skip to line 10 and re-invoke our master <code>curry</code> function. It re-receives <code>greet</code> and this time, <code>'Hello'</code>, and begins the madness all over again.</p>
<p>That’s <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Recursion">recursion</a>, my friends.</p>
<p><code>curry</code> is essentially an infinite loop of self-calling, parameter-hungry functions that won’t rest until their guest is full. Hospitality at its finest.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*AZKiupYSanV5iJSQWrtUwg.png" alt="1*AZKiupYSanV5iJSQWrtUwg" width="1600" height="769" loading="lazy"></p>
<h3 id="heading-back-at-line-2">Back at line 2</h3>
<p>Same parameters as before, except <code>initialParams</code> is <code>['Hello']</code> this time. Skip again to exit the cycle. Type our new variable into the console, <code>sayHello</code>. It’s another function, still expecting more parameters, but we’re getting warmer…</p>
<p>Let’s turn up the heat with <code>sayHelloToJohn = sayHello('John')</code>.</p>
<p>We’re inside line 4 again, and <code>nextParams</code> is <code>['John']</code>. Jump to the next debugger on line 6 and inspect <code>params</code>: it’s <code>['Hello', 'John']</code>! ?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*pej6yZ-vGvA2T9LgIIc-vg.png" alt="1*pej6yZ-vGvA2T9LgIIc-vg" width="1600" height="881" loading="lazy"></p>
<h3 id="heading-why-why-why">Why, why, why?</h3>
<p>Because remember, line 12 says “Hey <code>curriedFunction</code>, he gave me <code>'Hello'</code> last time and <code>‘John’</code> this time. Take them both in this array <code>[...initialParams, ...nextParams]</code>.”</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Ljvk2BMLxIsbJ09idgStdg.png" alt="1*Ljvk2BMLxIsbJ09idgStdg" width="1600" height="887" loading="lazy"></p>
<p>Now <code>curriedFunction</code> again compares the <code>length</code> of these <code>params</code> to <code>originalFunction</code>, and since <code>2 &lt; 3</code> we move to line 10 and call <code>curry</code> once again! And of course, we pass along <code>greet</code> and our 2 params, <code>['Hello', 'John']</code></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*EYv9jdo2id8tynbTI5SXYQ.png" alt="1*EYv9jdo2id8tynbTI5SXYQ" width="1600" height="762" loading="lazy"></p>
<p>We’re so close, let’s finish this and get the full greeting back!</p>
<p><code>sayHelloToJohnDoe = sayHelloToJohn('Doe')</code></p>
<p>I think we know what happens next.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*tMJvls2j9eAjrCGykVN84g.png" alt="1*tMJvls2j9eAjrCGykVN84g" width="1600" height="848" loading="lazy"><img src="https://cdn-media-1.freecodecamp.org/images/1*NHm1TMo8Tjk7jQVlGGa9zQ.png" alt="1*NHm1TMo8Tjk7jQVlGGa9zQ" width="1600" height="876" loading="lazy"><img src="https://cdn-media-1.freecodecamp.org/images/1*eTwjEYLKGCGJoqdP4Xe9hA.png" alt="1*eTwjEYLKGCGJoqdP4Xe9hA" width="1600" height="1336" loading="lazy"></p>
<h2 id="heading-the-deed-is-done">The Deed Is Done</h2>
<p><code>greet</code> got his parameters, <code>curry</code> stopped looping, and we’ve received our greeting: <code>Hello, John Doe</code>.</p>
<p>Play around with this function some more. Try supplying multiple or no parameters in one shot, get as crazy as you want. See how many times <code>curry</code> has to recurse before returning your expected output.</p>
<pre><code class="lang-js">curriedGreet(<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'John'</span>, <span class="hljs-string">'Doe'</span>);
curriedGreet(<span class="hljs-string">'Hello'</span>, <span class="hljs-string">'John'</span>)(<span class="hljs-string">'Doe'</span>);
curriedGreet()()(<span class="hljs-string">'Hello'</span>)()(<span class="hljs-string">'John'</span>)()()()()(<span class="hljs-string">'Doe'</span>);
</code></pre>
<p>Many thanks to <a target="_blank" href="https://medium.com/@_ericelliott">Eric Elliott</a> for introducing this to me, and even more thanks to you for appreciating <code>curry</code> with me. Until next time!</p>
<p><em>For more content like this, check out <a href="https://yazeedb.com">yazeedb.com</a>!</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to master advanced TypeScript patterns ]]>
                </title>
                <description>
                    <![CDATA[ By Pierre-Antoine Mills Learn how to create types for curry and Ramda _Photo by [Unsplash](https://unsplash.com/photos/2jXkA7GAz9M?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText" rel="noopener" target="_blank" title="">sergio sou... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/typescript-curry-ramda-types-f747e99744ab/</link>
                <guid isPermaLink="false">66c363c81a1cf73cbc81f145</guid>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ramda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 27 Feb 2019 17:35:32 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*s8OOdE6Qmx0HhbQwexsR1Q.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Pierre-Antoine Mills</p>
<h4 id="heading-learn-how-to-create-types-for-curry-and-ramda">Learn how to create types for curry and Ramda</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/gHHbXSKPmkakVPjav7Z2U9wiAA7Jcdfhde3t" alt="Image" width="800" height="347" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/photos/2jXkA7GAz9M?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" rel="noopener" target="_blank" title=""&gt;sergio souza on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" rel="noopener" target="<em>blank" title=")</em></p>
<p>Despite the popularity of currying and the rise of functional programming (and of TypeScript), it is still a hassle today to make use of curry and have <strong>proper type checks</strong>. Even famous libraries like Ramda do not provide generic types for their curry implementations (but we will).</p>
<p>However, you need no functional programming background to follow this guide. The guide is about currying but it is only a topic of my choice to teach you advanced TypeScript techniques. You just need to have practised a bit with TypeScript’s primitive types. And by the end of this walk-through, you will be a real TS wizard ?.</p>
<p>If you’re a functional programmer, you are probably already using currying to create powerful compositions and partial applications… And if you are a bit behind, it’s time to take the leap into functional programming, start shifting away from the imperative paradigm and solve problems faster, with ease, and promote reusability within your codebase.</p>
<p>At the end of this guide, you will know how to create <strong>powerful types</strong> like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0jtoHxd5Keq7fx457IldtUAfFG4ThZx8YoGq" alt="Image" width="800" height="237" loading="lazy"></p>
<p>In fact, Ramda does have some kind of mediocre types for curry. These types are not generic, <strong>hard-coded</strong>, limiting us to a certain amount of parameters. As of version 0.26.x, it only follows a <strong>maximum of 6 arguments</strong> and does not allow us to use its famous <strong>placeholder</strong> feature very easily with TypeScript. Why? It’s hard, but we agree that we had enough and we’re going to fix this!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/J6jdoXiM9B8ZUX02zbSXyE8-Aw-add4QIJP5" alt="Image" width="275" height="268" loading="lazy">
_Source: [Giphy](https://giphy.com/gifs/glitch-falling-JWXIa2DAQNoQg" rel="noopener" target="<em>blank" title=")</em></p>
<h4 id="heading-what-is-currying">What is currying?</h4>
<p>But before we start, let’s make sure that you have a very basic understanding of what currying is. Currying is the process of transforming a function that takes multiple arguments into a series of functions that take one argument at a time. Well that’s the theory.</p>
<p>I prefer examples much more than words, so let’s create a function that takes two numbers and that returns the result of their addition:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/iMtzZhZle3U2g9OSU2m8KJuYqaKlyJSy9xbm" alt="Image" width="800" height="90" loading="lazy"></p>
<p>The curried version of <code>simpleAdd</code> would be:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XwJ0THXXpg29kt4ji36b7AwRcJPFB48JnYg-" alt="Image" width="800" height="139" loading="lazy"></p>
<p>In this guide, I will first explain how to create TypeScript types that work with a standard curry implementation.</p>
<p>Then, we will evolve them into more <strong>advanced types</strong> that can allow curried functions to take 0 or more arguments.</p>
<p>And finally, we will be able to use “gaps” that abstract the fact that we are not capable or willing to provide an argument at a certain moment.</p>
<p><strong>TL;DR</strong>: We will create types for “classic curry” &amp; “advanced curry” (Ramda).</p>
<h3 id="heading-tuple-types">Tuple types</h3>
<p>Before we start learning the most advanced TypeScript techniques, I just want to make sure that you know <strong>tuples</strong>. Tuple types allow you to express an array where the type of a fixed number of elements is known. Let’s see an example:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/QEdtDxuaor9oABVKDXIz91aGwFeT7xyUQx8S" alt="Image" width="800" height="66" loading="lazy"></p>
<p>They can be used to enforce the kind of values inside a fixed size array:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/k9PLODTdaIIJJjsEhHg5i3S-AYPF8jcrMlXr" alt="Image" width="800" height="66" loading="lazy"></p>
<p>And can also be used in combination of rest parameters (or destructuring):</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/hhoq8DXKwuEGzzFnkUlHnu8Roc3sDHhpszc8" alt="Image" width="800" height="90" loading="lazy"></p>
<p>But before starting to build our awesome curry types, we’re going to do a bit of a warmup. We are going to create the first tools that we need to build one of the most basic curry types. Let’s go ahead.</p>
<p>Maybe you could guess… We are going to work with tuple types a lot. We’ll use them as soon as we extracted the parameters from the “original” curried function. So for the purpose of an example, let’s create a basic function:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/J9peTtIATeaP8jp76F1Kj7dwI5uonYaxpBcj" alt="Image" width="800" height="90" loading="lazy"></p>
<p>We extracted the parameter types from <code>fn00</code> thanks to the magic of <code>Parameters</code>. But it’s not so magical when you recode it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/U39IDHFcnsZ-dLyoZv6Fbno1Q0GZxZA7Ky-A" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/r4JRkERGOwT3aAYa96iNWbljXlP3Xr4qAPex" alt="Image" width="800" height="66" loading="lazy"></p>
<p>Good, it works just as <code>Parameters</code> does. Don’t be scared of <code>infer</code>, it is one of the most powerful keywords for building types. I will explain it in more detail right after we practiced some more:</p>
<h4 id="heading-head">Head</h4>
<p>Earlier, we learnt that a “classic curried” function takes one argument at a time. And we also saw that we can extract the parameter types in the form of a tuple type, very convenient.<br>So <code>Head</code> takes a tuple type <code>T</code> and returns the <strong>first type</strong> that it contains. This way, we’ll be able to know what argument type has to be taken at a time.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CHlmvskq9CbDrfVK8qEokxPJWHAoi0VK1OwK" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3BllaJUgiKEujqHjG--NxRLVwAuLXGx8N1A1" alt="Image" width="800" height="90" loading="lazy"></p>
<h4 id="heading-tail">Tail</h4>
<p>A “classic curried” function consumes arguments <strong>one by one</strong>. This means that when we consumed the <code>Head&lt;Params&amp;</code>lt;F&gt;&gt;, we somehow need to mov<strong>e on to the ne</strong>xt parameter that hasn’t been consumed yet. This is the <code>pur</code>pose of Tail, it conveniently removes the first entry that a tuple might contain.</p>
<p>As of TypeScript 3.4, we cannot “simply” remove the first entry of a tuple. So, we are going to work around this problem by using one very <strong>valid trick</strong>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/LJIrVYehTvk0lnEforfoD-XfLHApWxHytjgu" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Using <strong>function types</strong>, we were able to tell TypeScript to infer the tuple that we wanted. If you do not understand it yet, it is not a problem, this is just a warmup, remember?</p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/s1M8asD9pTUySKKNzdN8ThS7tI3nccrUYEW0" alt="Image" width="800" height="115" loading="lazy"></p>
<h4 id="heading-hastail">HasTail</h4>
<p>A curried function will return a function until all of it’s parameters have been <strong>consumed</strong>. This condition is reached when we called <code>Tail</code> enough times that there is no tail left, nothing’s left to consume:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aBBaqEP52ccLHllwPYRywYqKm15CkqhWISj1" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MSslnHhpafGiSGZIDIVtPskqgoP2ufaE4jEU" alt="Image" width="800" height="139" loading="lazy"></p>
<h3 id="heading-important-keywords">Important keywords</h3>
<p>You have encountered three important keywords: <code>**type**</code>, <code>**extends**</code> and <code>**infer**</code>. They can be pretty confusing for beginners, so these are the ideas they convey:</p>
<ul>
<li><code>**extends**</code>:<br>To keep it simple, you are allowed to think of it as if it was our dear old<br>JavaScript’s <code>**===**</code>. When you do so, you can see an <code>extends</code> statement as a <strong>simple ternary</strong>, and then it becomes much simpler to understand. In this case, <code>extends</code> is referred to as a <strong>conditional type</strong>.</li>
<li><code>**type**</code>:<br>I like to think of a type as if it was a <strong>function</strong>, but for types. It has an input, which are types (called <strong>generics</strong>) and has an output. The output depends on the “logic” of a type, and <code>extends</code> is that block of logic, similar to an <code>if</code> clause (or ternary).</li>
<li><code>**infer**</code>:<br>It is the magnifying glass of TypeScript, a beautiful inspecting tool that can <strong>extract types</strong> that are trapped inside different kinds of structures!</li>
</ul>
<p>I think that you understand both <code>extends</code> &amp; <code>type</code> well and this is why we are going to practice a bit more with <code>infer</code>. We’re going to extract types that are contained inside of different generic types. This is how you do it:</p>
<h4 id="heading-extract-a-propertys-type-from-an-object">Extract a property’s type from an object</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/e7TW4m93Q3H1MNUwVGDTM0Ref93NWtRGYfyC" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CWPhfFjc1-XnMUOy8RzZZ6q6iHwVR1WtZpzh" alt="Image" width="800" height="115" loading="lazy"></p>
<p><strong>Extract inner types from function types</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7Dz648h0mzss0jbsAMu1LxHdZTWYEkTNBMzD" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/iqqzJqqwwFGHGB0lLjU3gpMamLtR3lmAT5j-" alt="Image" width="800" height="90" loading="lazy"></p>
<p><strong>Extract generic types from a class or an interface</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/AaiIqlv-8HPqcnnItAEOCDwuiTlnIGVk38xq" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7SwlN4zLQb-GkVU0z53bg5G0nZrWrTFhf8ek" alt="Image" width="800" height="90" loading="lazy"></p>
<p><strong>Extract types from an array</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8qYXZ0XBi6NkAeQkOJAhTcN98KxyX1bHfgF0" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3WNFqxUGSvt-TJpJ6MoJc6EqyvraHbyLN6pN" alt="Image" width="800" height="90" loading="lazy"></p>
<p><strong>Extract types from a tuple</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Pb-j222BGW7K46xR9rgakjVeOwdFa2iG9k6N" alt="Image" width="800" height="139" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/jngjN2i1yCScQMVS6aHjYfPXAH1MZ5Y3ugYI" alt="Image" width="800" height="90" loading="lazy"></p>
<p>We tried to infer the type of the <strong>rest of the tuple</strong> into a type <code>B</code> but it did not work as expected. It is because TypeScript <strong>lacks</strong> of a feature that would allow us to <strong>deconstruct</strong> a tuple into another one. There is an active proposal that tackles these issues and you can expect improved manipulation for tuples in the future. This is why <code>Tail</code> is constructed the way it is.</p>
<p><code>infer</code> is very powerful and it will be your <strong>main tool</strong> for type manipulation.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1A2co54z4low60cVicsPW57m979hefFOjD7i" alt="Image" width="480" height="360" loading="lazy">
_Source: [Giphy](https://giphy.com/gifs/cheezburger-see-5K3Vw3jUqwV56" rel="noopener" target="<em>blank" title=")</em></p>
<h3 id="heading-curry-v0">Curry V0</h3>
<p>The warm-up ? is over, and you have the knowledge to build a “classic curry”. But before we start, let’s summarize (again) what it must be able to do:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/VE5KCCPIbmYfSrGgTsB2UCa2HBLkzD59uq7D" alt="Image" width="800" height="80" loading="lazy"></p>
<p>Our first curry type must take a tuple of <strong>parameters</strong> <code>P</code> and a <strong>return</strong> type <code>R</code>. It is a <strong>recursive</strong> function type that <strong>varies</strong> with the <strong>length of</strong> <code>P</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CgIczre6OeRg6wAd2vGYnPYZoAUj4K6Id7Vn" alt="Image" width="800" height="213" loading="lazy"></p>
<p>If <code>HasTail</code> reports <code>false</code>, it means that <strong>all</strong> the parameters were <strong>consumed</strong> and that it is time to <strong>return</strong> the return type <code>R</code> from the original function. Otherwise, there’s parameters <strong>left to consume</strong>, and we <strong>recurse</strong> within our type. Recurse? Yes, <code>CurryV0</code> describes a function that has a return type of <code>CurryV0</code> as long as there is a <code>Tail</code> (<code>HasTail&lt;P&gt; extend</code>s true).</p>
<p>This is as simple as it is. Here is the proof, without any implementation:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/6psb7bd4KeXlfysR-QlqZuua7cJXrRdiz4PN" alt="Image" width="800" height="56" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/7T9oP6a4U46tlbK3a6OMnM7AHuikSwMglTOs" alt="Image" width="800" height="87" loading="lazy"></p>
<p>But let’s rather visualize the recursion that happened above, step by step:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Keu0siYpxvmqzzNuh1iUsLaDI8hZwLm7JioR" alt="Image" width="800" height="116" loading="lazy"></p>
<p>And of course, type hints work for an <strong>unlimited</strong> amount of parameters ?:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/hbX-Y5WQPVnVVCPL02Gk7GI-VWCSjsPPnVf8" alt="Image" width="800" height="66" loading="lazy"></p>
<h3 id="heading-curry-v1">Curry V1</h3>
<p>Nice, but we forgot to handle the scenario where we pass a <strong>rest parameter</strong>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5s8kSoNvfuZ9MOZiXd7QPH1N0sAXJQZbAkal" alt="Image" width="800" height="103" loading="lazy"></p>
<p>We tried to use a rest parameter, but it won’t work because we actually expected a <strong>single</strong> parameter/argument that we earlier called <code>**arg0**</code>. So we want to take at least one argument <code>arg0</code> and we want to receive any extra (optional) arguments inside a rest parameter called <code>rest</code>. Let’s enable taking rest parameters by upgrading it with <code>Tail</code> &amp; <code>Partial</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/sqex95FBdDbnidAj6eq2Q2HZYCDbTqGV4kPk" alt="Image" width="800" height="164" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/AeHZhJ110EifXklHor2T4OULadbnwBxIHYwT" alt="Image" width="800" height="56" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5zjjyKorZYH5Ku93nwOiBFLUiLSySjtqjPCa" alt="Image" width="800" height="103" loading="lazy"></p>
<p>But we made a horrible mistake: the arguments are consumed very badly. According to what we wrote, this will not produce a single TS error:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Bob3CnZ0vCZqpmvqNpCsU55y8enzw17npqri" alt="Image" width="800" height="67" loading="lazy"></p>
<p>In fact there is a big <strong>design problem</strong> because we said that we would force taking a single <code>arg0</code>. Somehow, we are going to need to <strong>keep track</strong> of the arguments that are <strong>consumed</strong> at a time. So, we will first get rid of <code>arg0</code> and start tracking consumed parameters:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0uydMEZMPLc6-mr5YSZvzvEhCigKphy7bSTi" alt="Image" width="800" height="164" loading="lazy"></p>
<p>There, we made use of a <strong>constrained</strong> generic called <code>**T**</code> that is going to <strong>track</strong> any taken arguments. But now, it is completely broken, there is no more type checks because we said that we wanted to track <code>**any[]**</code> kind of parameters (the constraint). But not only that, <code>Tail</code> is completely useless because it only worked well when we took one argument at a time.</p>
<p>There is only one solution: <strong>some more tools</strong> ?.</p>
<h3 id="heading-recursive-types">Recursive types</h3>
<p>The following tools are going to be used to determine the next parameters to be consumed. How? By tracking the consumed parameters with <code>T</code> we should be able to <strong>guess what’s left</strong>.</p>
<p>Fasten your seat belt! You are about to learn another powerful technique ?:</p>
<h4 id="heading-last">Last</h4>
<p>Take your time to try to understand this complex yet very short type. This<br>example takes a tuple as a parameter and it extracts its last entry out:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/-Lz8QpB1iizm5Ht5AQXVopGg7spFsvcs3tTi" alt="Image" width="800" height="237" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/sB6a0YyguI4OIakTZKFLpn4UMN-4azlSCaQp" alt="Image" width="800" height="66" loading="lazy"></p>
<p>This example demonstrates the power of conditional types when used as an indexed type’s <strong>accessor</strong>. A what? A conditional type that accesses a type’s inner types in a command line fashion. For a more visual explanation:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/xgzVrAX64CLiquY0yLF0qthPMfF21skZpnRo" alt="Image" width="800" height="312" loading="lazy"></p>
<p>This technique is an <strong>ideal</strong> approach and a safe way to do <strong>recursion</strong> like we just did. But it is not only limited to recursion, it is a nice and a visual way to <strong>organise</strong> complex <strong>conditional types</strong>.</p>
<h3 id="heading-basic-tools-1">Basic tools #1</h3>
<p>Where were we? We said that we needed tools in order to <strong>track arguments</strong>. It means that we need to know what parameter types we can take, which ones have been consumed and which ones are the next to come. Let’s get started:</p>
<h4 id="heading-length">Length</h4>
<p>To do the analysis mentioned above, we will need to <strong>iterate</strong> over tuples. As<br>of TypeScript 3.4.x, there is no such iteration protocol that could allow us to iterate freely (like a <code>for</code>). Mapped types can map from a type to another, but they are too limiting for what we want to do. So, ideally, we would like to be able to manipulate some sort of <strong>counter</strong>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/wYeuZrAjfFdM6B9NXAUv3rCt0Cc8cIHXP23E" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2oF0r2YpVc-ukCwlfdbrXVCb-4upiPPMkXdC" alt="Image" width="800" height="115" loading="lazy"></p>
<p>By <strong>topping</strong> a tuple up with <code>any</code>, we created something that could be similar to a variable that can be <strong>incremented</strong>. However, <code>Length</code> is just about giving the size of a tuple, so it also works with any other kind of tuple:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8zKoWai2QpSrTYWPq6DXtRR6eiwsgqT3AlCf" alt="Image" width="800" height="66" loading="lazy"></p>
<h4 id="heading-prepend">Prepend</h4>
<p>It adds a type <code>E</code> at the <strong>top</strong> of a tuple <code>T</code> by using our first TS trick:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/xh7GuVMyKVoNGQc43TrYy-ZTvMrJNYNj7ZJB" alt="Image" width="800" height="137" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Z9ElT2pecidPyZKluv0V4pkzXDOljBqdRtAa" alt="Image" width="800" height="90" loading="lazy"></p>
<p>In <code>Length</code>’s examples, we manually increased a counter. So <code>Prepend</code> is the ideal candidate to be the base of a <strong>counter</strong>. Let’s see how it would work:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PpHPCHNCKbXVADtErbDfAMCY4HZq5YSstTEK" alt="Image" width="800" height="115" loading="lazy"></p>
<h4 id="heading-drop">Drop</h4>
<p>It takes a tuple <code>T</code> and drops the first <code>N</code> entries. To do so we are going to use the same techniques we used in <code>Last</code> and our brand new counter type:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3iXvCx2E5qJAQ3INjsoT-8DwmBqjbLPZaQ0k" alt="Image" width="800" height="233" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1TupbmvJtwskYCMImwUlAaMAei8DENnfL2t0" alt="Image" width="800" height="90" loading="lazy"></p>
<p>What happened?</p>
<p>The <code>Drop</code> type will recurse until <code>Length&lt;</code>;<strong>I&gt; m</strong>atches the val<code>u</code>e of N that we passed. In other words, the type of <code>i</code>ndex 0 is chosen by the conditional accessor until that condition is met. And we <code>used Prepend&amp;l</code>t;any, I&gt; so <strong>that we</strong> can increase a counter like we would do in a <code>loop. Thu</code>s, Length<i> is us<strong>ed as a</strong> recursion counter, and it is a way to freely iterate with TS.</i></p>
<h3 id="heading-curry-v3">Curry V3</h3>
<p>It’s been a long and tough road to get here, well done! There’s a reward for you ?.</p>
<p>Now, let’s say that we tracked that 2 parameters were consumed by our curry:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/F2IJOT9pYiP-yYyC5c-qXEkbUUZfHg3XXkiA" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Because we know the amount of consumed parameters, we can guess the ones that are still left to be consumed. Thanks to the help of <code>Drop</code>, we can do this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/BOHkaHyXDA91p4oDFZw1bQuJUFNZa8EjhgJ3" alt="Image" width="800" height="61" loading="lazy"></p>
<p>It looks like <code>Length</code> and <code>Drop</code> are precious tools. So let’s revamp our previous version of curry, the one that had a broken <code>Tail</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/uXP4yGlh8Eioxhzko8m9CMafcHHuNUfdUSvX" alt="Image" width="800" height="164" loading="lazy"></p>
<p>What did we do here?</p>
<p>First, <code>Drop&lt;Length&lt;</code>T&gt;, P&gt; means that we remove consumed parameters out.<br>Then, if th<code>e length of Drop&amp;l</code>t;Length<code>,</code> P&gt; is not equal to 0<strong>, our curry type h</strong>as to continue recursing with the dropped paramete<strong>rs</strong> until… Finally, when all <strong>of the</strong> parame<code>ters w</code>ere consumed, the Length of the dropped parameters is equal to 0, and the return type is R.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/t4FRePSoaR2dAZ4IC0GJkUxvm0S3bJdfUosX" alt="Image" width="300" height="200" loading="lazy">
_Source: [Giphy](https://giphy.com/gifs/ice-goat-LumJYWwnr6fSg" rel="noopener" target="<em>blank" title=")</em></p>
<h3 id="heading-curry-v4">Curry V4</h3>
<p>But we’ve got another error above: TS complains that our <code>Drop</code> is not of type <code>any[]</code>. Sometimes, TS will <strong>complain</strong> that a type is not the one you expected, but you know it is! So let’s add another tool to the collection:</p>
<h4 id="heading-cast">Cast</h4>
<p>It requires TS to <strong>re-check</strong> a type <code>X</code> against a type <code>Y</code>, and type <code>Y</code> will only be enforced if it fails. This way, we’re able to stop TS’s complaints:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0tjYGqAsnLhkMuRvnZJO0Vc450zaY3CGSafN" alt="Image" width="800" height="66" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PNWd5VOWmkDXtc3GhpQiKDCl7yHi38W4C2NT" alt="Image" width="800" height="90" loading="lazy"></p>
<p>And this is our previous curry, but without any complaint this time:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/PUf9EeCVGQni5QaKgjsD694AvetAXOirWY2p" alt="Image" width="800" height="164" loading="lazy"></p>
<p>Remember earlier, when we lost the type checks because we started tracking consumed parameters with <code>T extends any[]</code>? Well it has been fixed by casting <code>T</code> to <code>Partial&lt;</code>;P&gt;. We added a constrain<code>t withCast&lt;T,Pa</code>rtial</p><p>&gt;!</p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/TtZf06ws-uNqgtzb7R18yyTf4VpC08LbGVwa" alt="Image" width="800" height="56" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/RtUUGbB03dr9ZqLnQ5c6dNo7-9bMunXnfHHr" alt="Image" width="800" height="88" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/VwhBIFhYeITpAOfCeY2hqOazp0wedjPzEgQr" alt="Image" width="800" height="115" loading="lazy"></p>
<h3 id="heading-curry-v5">Curry V5</h3>
<p>Maybe you thought that we were able to take rest parameters. Well, I am very sorry to inform you that we are not there yet. This is the reason why:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/qJUVcf7HJye7spkqBobl9Nlg6afIsspcYhfM" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Because rest parameters can be <strong>unlimited</strong>, TS’s best guess is that the length of our tuple is a <code>number</code>, it’s kind of clever! So, we <strong>cannot</strong> make use of <code>Length</code> while dealing with rest parameters. Don’t be sad, it’s not so bad:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/c-770wkJstOyLT4lV0DnwdM0LJqhDKY8zAO4" alt="Image" width="800" height="164" loading="lazy"></p>
<p>When all the non-rest parameters are consumed, <code>Drop&lt;Length&lt;</code>;T&gt;,P&gt; can <code>only ma</code>tch […any[]]. Thanks to th<code>is, we used</code> [any,…any[] as a c<strong>ond</strong>ition to end the recursion.</p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/QKEwC3TzYAW6nm8jHvtg9nWtWQbOBogY0bLW" alt="Image" width="800" height="56" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/4197K0vwe6DMbxp1QHp0hLGCgbDLv71zDqJp" alt="Image" width="800" height="67" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/M5msqRMawT7UuEeMQ80U02YrKI6mZxjKTwGp" alt="Image" width="800" height="115" loading="lazy"></p>
<p>Everything works like a charm ?. You just got yourself a smart, g<strong>eneric,</strong> v<strong>ariadic curry type.</strong> You will be able play with it very soon… But before you do so, what if I told you that our type can get even more awesome?</p>
<h3 id="heading-placeholders">Placeholders</h3>
<p>How awesome? We are going give our type the ability to <strong>understand</strong> partial application of <strong>any combination of arguments</strong>, on any position. According to Ramda’s documentation, we can do so by using a <strong>placeholder</strong> called <code>_</code>. It states that for any curried function <code>f</code>, these calls are equivalent:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/8hxR2PKAItfGpkkI451SiG84L3o8JsQFvvnW" alt="Image" width="800" height="213" loading="lazy"></p>
<p>A placeholder or “gap” is an object that abstracts the fact that we are not<br>capable or willing to provide an argument at a certain moment. Let’s start by<br>defining what a placeholder is. We can directly grab the one from Ramda:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/5qEGVxAeMGTSN77Itw2H9qFCQYqIZgKTgU72" alt="Image" width="800" height="115" loading="lazy"></p>
<p>Earlier, we have learnt how to do our first type iterations by increasing a tuple’s length. In fact, it is a bit confusing to use <code>Length</code> and <code>Prepend</code> on our counter type. And to make it <strong>clearer</strong>, we will refer to that counter as an <strong>iterator</strong> from now on. Here’s some new aliases just for this purpose:</p>
<h4 id="heading-pos-position">Pos (Position)</h4>
<p>Use it to query the position of an iterator:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2XiBFO4R97iAoam8JVXck1SIvt-yNFLojq0A" alt="Image" width="800" height="90" loading="lazy"></p>
<h4 id="heading-next-1">Next (+1)</h4>
<p>It brings the position of an iterator up:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/hI4x2iy4H1smshUSP9KICQ6Lk9a-IYYXBS7m" alt="Image" width="800" height="90" loading="lazy"></p>
<h4 id="heading-prev-1">Prev (-1)</h4>
<p>It brings the position of an iterator down:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/OmpB2K2jHbNkx1Ms-W4YCSK0DkuKjf6dXEPl" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Let’s test them:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Lkedx1ruYGBRIwrO-S9HcdYSaWrYuDXOYjBG" alt="Image" width="800" height="139" loading="lazy"></p>
<h4 id="heading-iterator">Iterator</h4>
<p>It creates an iterator (our counter type) at a position defined by <code>Index</code> and is able to start off from another iterator’s position by using <code>From</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/AJsinWfsGJmL6cV1-wGQXv137cng1eGL1mbE" alt="Image" width="800" height="184" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/kJbgjeGI0MHUhp6WtpVXhCG83m3FleLPFgOo" alt="Image" width="800" height="139" loading="lazy"></p>
<h3 id="heading-basic-tools-2">Basic tools #2</h3>
<p>Good, so what do we do next? We need to <strong>analyze</strong> whenever a placeholder is passed as an argument. From there, we will be able to tell if a parameter has been “skipped” or “postponed”. Here’s some more tools for this purpose:</p>
<h4 id="heading-reverse">Reverse</h4>
<p>Believe it or not, we still lack a few basic tools. <code>Reverse</code> is going to give us the freedom that we need. It takes a tuple <code>T</code> and turns it the other way around into a tuple <code>R</code>, thanks to our brand new iteration types:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/mV237zmN8G6M5OGxtkvsQLKCS5UIbtQCj4ff" alt="Image" width="800" height="213" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/16lb4ggNoGBQ328a-FaQUnBNlVYB0jFP4uqt" alt="Image" width="800" height="115" loading="lazy"></p>
<h4 id="heading-concat">Concat</h4>
<p>And from <code>Reverse</code>, <code>Concat</code> was born. It simply takes a tuple <code>T1</code> and merges it with another tuple <code>T2</code>. It’s kind of what we did in <code>test59</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/eKKnFeG25Qso0D1O2Zqc4BGnZrRc7JOo683l" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/KTTlVtOGKv9Sx3phQnlCMcjz5WUI3nOQzSUZ" alt="Image" width="800" height="66" loading="lazy"></p>
<h4 id="heading-append">Append</h4>
<p>Enabled by <code>Concat</code>, <code>Append</code> can add a type <code>E</code> at the end of a tuple <code>T</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Wl-T8NRPiEAwLXmZGCjaNLNAZltxNCIgl9w8" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/UMvrhshMeARwFndD-CUp0BNPh0Ew08STCXzV" alt="Image" width="800" height="66" loading="lazy"></p>
<h3 id="heading-gap-analysis">Gap analysis</h3>
<p>We now have enough tools to perform <strong>complex type checks</strong>. But it’s been a while since we discussed this “gap” feature, how does it work again? When a gap is specified as an argument, its matching parameter is <strong>carried over</strong> to the next step (to be taken). So let’s define types that understand gaps:</p>
<h4 id="heading-gapof">GapOf</h4>
<p>It checks for a placeholder in a tuple <code>T1</code> at the position described by an iterator <code>I</code>. If it is found, the matching type is <strong>collected</strong> at the same position in <code>T2</code> and carried over (saved) for the next step through <code>TN</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SuAOfNSC7M1N0EMcE79GcpyON-fQsHvgzm68" alt="Image" width="800" height="116" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/qiwU1IXQv2b9zRz4VksfFzK9Y9HxfewhUDmy" alt="Image" width="800" height="82" loading="lazy"></p>
<h4 id="heading-gapsof">GapsOf</h4>
<p>Don’t be impressed by this one. It calls <code>Gap</code> over <code>T1</code> &amp; <code>T2</code> and stores the results in <code>TN</code>. And when it’s done, it concats the results from <code>TN</code> to the parameter types that are left to be taken (for the next function call):</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Lop0oZKqLXoe7Wv15mXq9kEoEBdalufa-Tpb" alt="Image" width="800" height="172" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/6i2Xc1q6E6f3y8Agca4uOKkEKK5CbKjt6fDQ" alt="Image" width="800" height="78" loading="lazy"></p>
<h4 id="heading-gaps">Gaps</h4>
<p>This last piece of the puzzle is to be applied to the tracked parameters <code>T</code>. We will make use of <strong>mapped types</strong> to explain that is is possible replace any argument with a <strong>placeholder</strong>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Ib8MHDLBtIhnPAoCobC8-G69cTew-umwBGXN" alt="Image" width="800" height="115" loading="lazy"></p>
<p>A mapped type allows one to iterate and <strong>alter properties</strong> of another type. In this case, we altered <code>T</code> so that each entry can be of the placeholder type. And thanks to <code>?</code>, we explained that each entry of <code>T</code> is optional. It means that we no longer have the need to use <code>Partial</code> on the tracked parameters.</p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/E3fgCRtmWtHBFBv5vdxT7OdzCaXBkYWt2uoH" alt="Image" width="800" height="90" loading="lazy"></p>
<p>Ugh, we never said that we could take <code>undefined</code>! We just wanted to be able to omit a part of <code>T</code>. It is a <strong>side effect</strong> of using the <code>?</code> operator. But it is not that bad, we can fix this by re-mapping with <code>NonNullable</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/h6zieDXDvoLGLsl8LNP5aLC508Hgou04fw1x" alt="Image" width="800" height="115" loading="lazy"></p>
<p>So let’s put the two together and get what we wanted:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/TlR8l43TjvH1FVVKOqqnob38k2PyMk1QZDDy" alt="Image" width="800" height="66" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0wvpT0toDEO1MWpZqJnbiC9nl1QTnOKg8NBS" alt="Image" width="800" height="90" loading="lazy"></p>
<h3 id="heading-curry-v6">Curry V6</h3>
<p>We’ve built the last tools we will ever need for our curry type. It is now time to put the last pieces together. Just to remind you, <code>Gaps</code> is our new replacement for <code>Partial</code>, and <code>GapsOf</code> will replace our previous <code>Drop</code>:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/RtM7MwxrFcQmlr4oI0ZvOAT7R1Vb2WVz0KZs" alt="Image" width="800" height="164" loading="lazy"></p>
<p>Let’s test it:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/tnIPwlUxOi4MFOeGA83BhsMdReeZsesE5YsP" alt="Image" width="800" height="56" loading="lazy"></p>
<p>In order to make sure that everything works as intended, I am going to force the values that are to be taken by the curried example function:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/Y9DQVOnURiopXB7ved6yQwawFzS8zjH-d9oT" alt="Image" width="800" height="90" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/tkeaGYZtras0kQcUjKSCHt9aqBgeYoZlLv7t" alt="Image" width="800" height="98" loading="lazy"></p>
<p>There is just a little problem: it seems like we’re a bit ahead of Ramda! Our type can understand very complex placeholder usages. In other words, Ramda’s placeholders just <strong>don’t work</strong> when they’re combined with rest parameters ?:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2IZ4S7mBajskuaaDrTdD2GXUAQEnCiZ1-jCp" alt="Image" width="800" height="69" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/NsZjbAymZITMsw0wKe0Q32LOspQGCGRJqVv5" alt="Image" width="800" height="73" loading="lazy"></p>
<p>However, even if this looks perfectly correct, it will result in a complete crash. This happens because the implementation of Ramda’s curry does not deal well with combinations of <strong>placeholders and rest parameters</strong>. This is why I opened a ticket with Ramda on Github, in the hope that the types we’ve just created could one day work in harmony with the library.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/gfN-AekkhygN4jzQF95nyvODxjc8D-BNUyyf" alt="Image" width="480" height="358" loading="lazy">
_Source: [Giphy](https://giphy.com/gifs/jess-3osxYciDsUpfwZXZV6" rel="noopener" target="<em>blank" title=")</em></p>
<h3 id="heading-curry">Curry</h3>
<p>This is very cute, but we have one last problem to solve: <strong>parameter hints</strong>. I don’t know about you, but I use parameter hints a lot. It is very useful to know the names of the parameters that you’re dealing with. The version above does not allow for these kind of hints. Here is the fix:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/j6cwCzOiM5lQBIaH-OKjbAzMa-VZ7quGpG63" alt="Image" width="800" height="180" loading="lazy"></p>
<p>I admit, it’s completely awful! However, we got hints for <strong>Visual Studio Code</strong>.<br>What did we do here? We just replaced the parameter types <code>P</code> &amp; <code>R</code> that used to stand for parameter types and return type, respectively. And instead, we used the <strong>function type</strong> <code>F</code> from which we extracted the equivalent of <code>P</code> with <code>Parameters&lt;</code>;F&gt;<code>;</code> and R <code>with ReturnT</code>ype. Thus, TypeScript is able to conserve the name of the parameters, even after currying:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/beEnT-ydrNb4m1QxH9HdcWzAym01d9P905lw" alt="Image" width="800" height="115" loading="lazy"></p>
<p>There’s just one thing: when using gaps, we’ll lose the name of a parameter.</p>
<p><em>A word for IntelliJ users only: You won’t be able to benefit from proper hints. I recommend that you switch to Visual Studio Code as soon as possible. And it is community-driven, free, much (much) faster, and supports key bindings for IntelliJ users. :)</em></p>
<h3 id="heading-last-words">LAST WORDS</h3>
<p>Finally, I would like to inform you that there is a current proposal for <a target="_blank" href="https://github.com/Microsoft/TypeScript/issues/5453">variadic types</a>. What you’ve learned here is not going to become obsolete — this proposal aims to ease the <strong>most common</strong> tuple type manipulations, so it is a very good thing for us. In a close future, it will enable easier tuple concatenations like the <code>Append</code>, <code>Concat</code>, and <code>Prepend</code> we’ve built, as well as destructuring and a better way to describe variable function parameters.</p>
<p>That’s it. I know that it’s a lot to digest at once, so that’s why I released a <a target="_blank" href="https://github.com/pirix-gh/medium/blob/master/types-curry-ramda/src/index.ts">developer version</a> of this article. You can clone it, test it, and change it with TypeScript 3.3.x and above. Keep it close to you and learn from it until you become more comfortable with the different techniques ?.</p>
<p><strong>High-five ? if you enjoyed this guide, and stay tuned for my next article!</strong></p>
<p><strong>EDIT:</strong> <a target="_blank" href="https://github.com/DefinitelyTyped/DefinitelyTyped/pull/33628">It’s available for Ramda 0.26.1</a></p>
<p><strong>Thanks for reading</strong>. And if you have any questions or remarks, you are more<br>than welcome to leave a comment.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use Wikipedia’s search API to build a user interface with RamdaJS ]]>
                </title>
                <description>
                    <![CDATA[ By Yazeed Bzadough In this tutorial, we’ll build a UI using Wikipedia’s public search API along with some JavaScript + RamdaJS. Getting Started Here’s the GitHub link and Codesandbox link. Open your terminal and pick a directory to clone it. git clon... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-wikipedias-api-search-with-ramdajs-b3c1a069d7af/</link>
                <guid isPermaLink="false">66d4619ba326133d12440aa0</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Functional Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ramda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 27 Nov 2018 01:49:56 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/0*JFmZsramtJjAI0yJ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yazeed Bzadough</p>
<p>In this tutorial, we’ll build a UI using Wikipedia’s public search API along with some JavaScript + RamdaJS.</p>
<h3 id="heading-getting-started">Getting Started</h3>
<p>Here’s the <a target="_blank" href="https://github.com/yazeedb/ramda-wikipedia-search">GitHub link</a> and <a target="_blank" href="https://codesandbox.io/s/y2zpq2xw39">Codesandbox link</a>. Open your terminal and pick a directory to clone it.</p>
<pre><code>git clone [https:<span class="hljs-comment">//github.com/yazeedb/ramda-wikipedia-search](https://github.com/yazeedb/ramda-wikipedia-search)</span>
cd ramda-wikipedia-search
yarn install (or npm install)
</code></pre><p>The <code>master</code> branch has the finished project, so check out the <code>start</code> branch if you wish to code along.</p>
<p><code>git checkout start</code></p>
<p>And start the project!</p>
<p><code>npm start</code></p>
<p>Your browser should automatically open <a target="_blank" href="http://localhost:1234/">localhost:1234</a>.</p>
<h3 id="heading-getting-the-input-value"><strong>Getting the Input Value</strong></h3>
<p>Here’s the initial app.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*Wu4Qmu5newQZWGzt.png" alt="0*Wu4Qmu5newQZWGzt" width="1426" height="800" loading="lazy"></p>
<p>To capture the user’s input as they type, our <code>input</code> element needs an event listener.</p>
<p>Your <code>src/index.js</code> file is already hooked up and ready to go. You’ll notice we imported Bootstrap for styling.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*qHfza67WgAEMZ-by.png" alt="0*qHfza67WgAEMZ-by" width="1600" height="537" loading="lazy"></p>
<p>Let’s add a dummy event listener to get things going.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'bootstrap/dist/css/bootstrap.min.css'</span>;

<span class="hljs-keyword">const</span> inputElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'input'</span>);

inputElement.addEventListener(<span class="hljs-string">'keyup'</span>, <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'value:'</span>, event.target.value);
});
</code></pre>
<p>We know <code>event.target.value</code>'s the standard way to access an input’s value. Now it shows the value.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*NLxwt8JdO7YkAUNV.png" alt="0*NLxwt8JdO7YkAUNV" width="1600" height="352" loading="lazy"></p>
<p>How can Ramda help us achieve the following?</p>
<ul>
<li>Grab <code>event.target.value</code></li>
<li>Trim the output (strip leading/trailing whitespace)</li>
<li>Default to empty string if <code>undefined</code></li>
</ul>
<p>The <code>pathOr</code> function can actually handle the first and third bullet points. It takes three parameters: the default, the path, and the data.</p>
<p>So the following works perfectly</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { pathOr } <span class="hljs-keyword">from</span> <span class="hljs-string">'ramda'</span>;

<span class="hljs-keyword">const</span> getInputValue = pathOr(<span class="hljs-string">''</span>, [<span class="hljs-string">'target'</span>, <span class="hljs-string">'value'</span>]);
</code></pre>
<p>If <code>event.target.value</code> is <code>undefined</code>, we’ll get an empty string back!</p>
<p>Ramda also has a <code>trim</code> function, so that solves our whitespace issue.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { pathOr, trim } <span class="hljs-keyword">from</span> <span class="hljs-string">'ramda'</span>;

<span class="hljs-keyword">const</span> getInputValue = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> trim(pathOr(<span class="hljs-string">''</span>, [<span class="hljs-string">'target'</span>, <span class="hljs-string">'value'</span>], event));
</code></pre>
<p>Instead of nesting those functions, let’s use <code>pipe</code>. See <a target="_blank" href="a-quick-intro-to-pipe-and-compose">my article on pipe</a> if it’s new to you.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { pathOr, pipe, trim } <span class="hljs-keyword">from</span> <span class="hljs-string">'ramda'</span>;

<span class="hljs-keyword">const</span> getInputValue = pipe(
  pathOr(<span class="hljs-string">''</span>, [<span class="hljs-string">'target'</span>, <span class="hljs-string">'value'</span>]),
  trim
);
</code></pre>
<p>We now have a composed function that takes an <code>event</code> object, grabs its <code>target.value</code>, defaults to <code>''</code>, and trims it.</p>
<p>Beautiful.</p>
<p>I recommend storing this in a separate file. Maybe call it <code>getInputValue.js</code> and use the default export syntax.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*EKKGBfZBV5jhZRl9S7wORw.png" alt="1*EKKGBfZBV5jhZRl9S7wORw" width="611" height="251" loading="lazy"></p>
<h3 id="heading-getting-the-wikipedia-url">Getting the Wikipedia URL</h3>
<p>As of this writing, Wikipedia’s API search URL is <a target="_blank" href="https://en.wikipedia.org/w/api.php?origin=*&amp;action=opensearch&amp;search=">https://en.wikipedia.org/w/api.php?origin=*&amp;action=opensearch&amp;search=</a></p>
<p>For an actual search, just append a topic. If you need bears, for example, the URL looks like this:</p>
<p><a target="_blank" href="https://en.wikipedia.org/w/api.php?origin=*&amp;action=opensearch&amp;search=bears">https://en.wikipedia.org/w/api.php?origin=*&amp;action=opensearch&amp;search=bears</a></p>
<p>We’d like a function that takes a topic and returns the full Wikipedia search URL. As the user types we build the URL based off their input.</p>
<p>Ramda’s <code>concat</code> works nicely here.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { concat } <span class="hljs-keyword">from</span> <span class="hljs-string">'ramda'</span>;

<span class="hljs-keyword">const</span> getWikipediaSearchUrlFor = concat(
  <span class="hljs-string">'https://en.wikipedia.org/w/api.php?origin=*&amp;action=opensearch&amp;search='</span>
);
</code></pre>
<p><code>concat</code>, true to its name, concatenates strings and arrays. It’s curried so providing the URL as one argument returns a function expecting a second string. See <a target="_blank" href="https://medium.com/front-end-hacking/how-does-javascripts-curry-actually-work-8d5a6f891499">my article on currying</a> if it’s new!</p>
<p>Put that code into a module called <code>getUrl.js</code>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*K-qJqHr60zKPUe_-5ql5cw.png" alt="1*K-qJqHr60zKPUe_-5ql5cw" width="949" height="289" loading="lazy"></p>
<p>Now let’s update <code>index.js</code>. Import our two new modules, along with <code>pipe</code> and <code>tap</code> from Ramda.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'bootstrap/dist/css/bootstrap.min.css'</span>;
<span class="hljs-keyword">import</span> { pipe, tap } <span class="hljs-keyword">from</span> <span class="hljs-string">'ramda'</span>;
<span class="hljs-keyword">import</span> getInputValue <span class="hljs-keyword">from</span> <span class="hljs-string">'./getInputValue'</span>;
<span class="hljs-keyword">import</span> getUrl <span class="hljs-keyword">from</span> <span class="hljs-string">'./getUrl'</span>;

<span class="hljs-keyword">const</span> makeUrlFromInput = pipe(
  getInputValue,
  getUrl,
  tap(<span class="hljs-built_in">console</span>.warn)
);

<span class="hljs-keyword">const</span> inputElement = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'input'</span>);

inputElement.addEventListener(<span class="hljs-string">'keyup'</span>, makeUrlFromInput);
</code></pre>
<p>This new code’s constructing our request URL from the user’s input and logging it via <code>tap</code>.</p>
<p>Check it out.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*xZxxcq2MpNutqcfvzTUXKQ.png" alt="1*xZxxcq2MpNutqcfvzTUXKQ" width="1600" height="711" loading="lazy"></p>
<h3 id="heading-making-the-ajax-request"><strong>Making the AJAX Request</strong></h3>
<p>Next step is mapping that URL to an AJAX request and collecting the JSON response.</p>
<p>Replace <code>makeUrlFromInput</code> with a new function, <code>searchAndRenderResults</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> searchAndRenderResults = pipe(
  getInputValue,
  getUrl,
  <span class="hljs-function">(<span class="hljs-params">url</span>) =&gt;</span>
    fetch(url)
      .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())
      .then(<span class="hljs-built_in">console</span>.warn)
);
</code></pre>
<p>Don’t forget to change your event listener too!</p>
<pre><code class="lang-js">inputElement.addEventListener(<span class="hljs-string">'keyup'</span>, searchAndRenderResults);
</code></pre>
<p>Here’s our result.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*gMD8q10P6eFtW7qLNz7uXQ.png" alt="1*gMD8q10P6eFtW7qLNz7uXQ" width="1600" height="735" loading="lazy"></p>
<h3 id="heading-making-a-results-component"><strong>Making a Results Component</strong></h3>
<p>Now that we have JSON, let’s create a component that pretties it up.</p>
<p>Add <code>Results.js</code> to your directory.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*5L38JxtvqbyjxfVeM2lRvA.png" alt="1*5L38JxtvqbyjxfVeM2lRvA" width="694" height="178" loading="lazy"></p>
<p>Look back at our Wikipedia search JSON response. Note its shape. It’s an array with the following indices:</p>
<ol>
<li>Query (what you searched for)</li>
<li>Array of result names</li>
<li>Array of summaries</li>
<li>Array of links to results</li>
</ol>
<p>Our component can take an array of this shape and return a nicely formatted list. Through ES6 array destructuring, we can use that as our function signature.</p>
<p>Edit <code>Results.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ([query, names, summaries, links]) =&gt; <span class="hljs-string">`
  &lt;h2&gt;Searching for "<span class="hljs-subst">${query}</span>"&lt;/h2&gt;
  &lt;ul class="list-group"&gt;
    <span class="hljs-subst">${names.map(
      (name, index) =&gt; <span class="hljs-string">`
        &lt;li class="list-group-item"&gt;
          &lt;a href=<span class="hljs-subst">${links[index]}</span> target="_blank"&gt;
            &lt;h4&gt;<span class="hljs-subst">${name}</span>&lt;/h4&gt;
          &lt;/a&gt;
          &lt;p&gt;<span class="hljs-subst">${summaries[index]}</span>&lt;/p&gt;
        &lt;/li&gt;
      `</span>
    )}</span>
  &lt;/ul&gt;
`</span>;
</code></pre>
<p>Let’s go step by step.</p>
<ul>
<li>It’s a function that takes an array of our expected elements: <code>query</code>, <code>names</code>, <code>summaries</code>, and <code>links</code>.</li>
<li>Using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">ES6 template literals</a>, it returns an HTML string with a title and a list.</li>
<li>Inside the <code>&lt;ul&gt;</code> we map <code>names</code> to <code>&lt;li&gt;</code> tags, so one for each.</li>
<li>Inside those are <code>&lt;a&gt;</code> tags pointing to each result’s link. Each link opens in a new tab.</li>
<li>Below the link is a paragraph summary.</li>
</ul>
<p>Import this in <code>index.js</code> and use it like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// ...</span>

<span class="hljs-keyword">import</span> Results <span class="hljs-keyword">from</span> <span class="hljs-string">'./Results'</span>;

<span class="hljs-comment">// ...</span>

<span class="hljs-keyword">const</span> searchAndRenderResults = pipe(
  getInputValue,
  getUrl,
  <span class="hljs-function">(<span class="hljs-params">url</span>) =&gt;</span>
    fetch(url)
      .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())
      .then(Results)
      .then(<span class="hljs-built_in">console</span>.warn)
);
</code></pre>
<p>This passes the Wikipedia JSON to <code>Results</code> and logs the result. You should be seeing a bunch of HTML in your DevTools console!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*_A5qIZOpTB3HPsga.png" alt="0*_A5qIZOpTB3HPsga" width="1600" height="701" loading="lazy"></p>
<p>All that’s left is to render it to the DOM. A simple <code>render</code> function should do the trick.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> render = <span class="hljs-function">(<span class="hljs-params">markup</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> resultsElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'results'</span>);

  resultsElement.innerHTML = markup;
};
</code></pre>
<p>Replace <code>console.warn</code> with the <code>render</code> function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> searchAndRenderResults = pipe(
  getInputValue,
  getUrl,
  <span class="hljs-function">(<span class="hljs-params">url</span>) =&gt;</span>
    fetch(url)
      .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())
      .then(Results)
      .then(render)
);
</code></pre>
<p>And check it out!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*v6by39wYex3-NwIl.png" alt="0*v6by39wYex3-NwIl" width="1600" height="750" loading="lazy"></p>
<p>Each link should open in a new tab.</p>
<h3 id="heading-removing-those-weird-commas"><strong>Removing Those Weird Commas</strong></h3>
<p>You may have noticed something off about our fresh UI.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*ZAeJJS-ZP1YNAv5f.png" alt="0*ZAeJJS-ZP1YNAv5f" width="1600" height="750" loading="lazy"></p>
<p>It has extra commas! Why??</p>
<h3 id="heading-template-literals">Template Literals</h3>
<p>It’s all about how template literals join things. If you stick in an array, it’ll join it using the <code>toString()</code> method.</p>
<p>See how this becomes joined?</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> joined = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>].toString();

<span class="hljs-built_in">console</span>.log(joined);
<span class="hljs-comment">// 1,2,3</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> joined);
<span class="hljs-comment">// string</span>
</code></pre>
<p>Template literals do that if you put arrays inside of them.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> nums = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
<span class="hljs-keyword">const</span> msg = <span class="hljs-string">`My favorite nums are <span class="hljs-subst">${nums}</span>`</span>;

<span class="hljs-built_in">console</span>.log(msg);
<span class="hljs-comment">// My favorite nums are 1,2,3</span>
</code></pre>
<p>You can fix that by joining the array without commas. Just use an empty string.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> nums = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
<span class="hljs-keyword">const</span> msg = <span class="hljs-string">`My favorite nums are <span class="hljs-subst">${nums.join(<span class="hljs-string">''</span>)}</span>`</span>;

<span class="hljs-built_in">console</span>.log(msg);
<span class="hljs-comment">// My favorite nums are 123</span>
</code></pre>
<p>Edit <code>Results.js</code> to use the <code>join</code> method.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ([query, names, summaries, links]) =&gt; <span class="hljs-string">`
  &lt;h2&gt;Searching for "<span class="hljs-subst">${query}</span>"&lt;/h2&gt;
  &lt;ul class="list-group"&gt;
    <span class="hljs-subst">${names
      .map(
        (name, index) =&gt; <span class="hljs-string">`
        &lt;li class="list-group-item"&gt;
          &lt;a href=<span class="hljs-subst">${links[index]}</span> target="_blank"&gt;
            &lt;h4&gt;<span class="hljs-subst">${name}</span>&lt;/h4&gt;
          &lt;/a&gt;
          &lt;p&gt;<span class="hljs-subst">${summaries[index]}</span>&lt;/p&gt;
        &lt;/li&gt;
      `</span>
      )
      .join(<span class="hljs-string">''</span>)}</span>
  &lt;/ul&gt;
`</span>;
</code></pre>
<p>Now your UI’s much cleaner.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*JFmZsramtJjAI0yJ.png" alt="0*JFmZsramtJjAI0yJ" width="1600" height="739" loading="lazy"></p>
<h3 id="heading-fixing-a-little-bug"><strong>Fixing a Little Bug</strong></h3>
<p>I found a little bug while building this. Did you notice it?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*8qwAFsWU_6nKuXUH.png" alt="0*8qwAFsWU_6nKuXUH" width="600" height="277" loading="lazy"></p>
<p>Emptying the <code>input</code> throws this error.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*-aUVIsS0rtQoVomy.png" alt="0*-aUVIsS0rtQoVomy" width="1600" height="141" loading="lazy"></p>
<p>That’s because we’re sending an AJAX request without a search topic. Check out the URL in your Network tab.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*4cDzbOBm8Sw7KDwy.png" alt="0*4cDzbOBm8Sw7KDwy" width="1600" height="567" loading="lazy"></p>
<p>That link points to a default HTML page. We didn’t get JSON back because we didn’t specify a search topic.</p>
<p>To prevent this from happening we can avoid sending the request if the <code>input</code>'s empty.</p>
<p>We need a function that <strong>does nothing</strong> if the <code>input</code>'s empty, and <strong>does the search</strong> if it’s filled.</p>
<p>Let’s first create a function called <code>doNothing</code>. You can guess what it looks like.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> doNothing = <span class="hljs-function">() =&gt;</span> {};
</code></pre>
<p>This is better known as <code>noOp</code>, but I like <code>doNothing</code> in this context.</p>
<p>Next remove <code>getInputValue</code> from your <code>searchAndRenderResults</code> function. We need a bit more security before using it.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> searchAndRenderResults = pipe(
  getUrl,
  <span class="hljs-function">(<span class="hljs-params">url</span>) =&gt;</span>
    fetch(url)
      .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())
      .then(Results)
      .then(render)
);
</code></pre>
<p>Import <code>ifElse</code> and <code>isEmpty</code> from Ramda.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { ifElse, isEmpty, pipe, tap } <span class="hljs-keyword">from</span> <span class="hljs-string">'ramda'</span>;
</code></pre>
<p>Add another function, <code>makeSearchRequestIfValid</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> makeSearchRequestIfValid = pipe(
  getInputValue,
  ifElse(isEmpty, doNothing, searchAndRenderResults)
);
</code></pre>
<p>Take a minute to absorb that.</p>
<p>If the input value’s empty, do nothing. Else, search and render the results.</p>
<p>You can gather that information just by reading the function. <em>That’s</em> expressive.</p>
<p>Ramda’s <a target="_blank" href="https://ramdajs.com/docs/#isEmpty">isEmpty</a> function works with strings, arrays, objects.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*VSddS4PKGUKcW_NC.png" alt="0*VSddS4PKGUKcW_NC" width="738" height="300" loading="lazy"></p>
<p>This makes it perfect to test our input value.</p>
<p><code>ifElse</code> fits here because when <code>isEmpty</code> returns true, <code>doNothing</code> runs. Otherwise <code>searchAndRenderResults</code> runs.</p>
<p>Lastly, update your event handler.</p>
<pre><code class="lang-js">inputElement.addEventListener(<span class="hljs-string">'keyup'</span>, makeSearchRequestIfValid);
</code></pre>
<p>And check the results. No more errors when clearing the <code>input</code>!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*rKRi-EEHpN0FaRER.png" alt="0*rKRi-EEHpN0FaRER" width="600" height="277" loading="lazy"></p>
<p>This tutorial was from <strong>my</strong> <strong>completely free</strong> <strong>course</strong> on Educative.io, <a target="_blank" href="https://www.educative.io/collection/5070627052453888/5738600293466112?authorName=Yazeed%20Bzadough">Functional Programming Patterns With RamdaJS</a>!</p>
<p>Please consider taking/sharing it if you enjoyed this content.</p>
<p>It’s full of lessons, graphics, exercises, and runnable code samples to teach you a basic functional programming style using RamdaJS.</p>
<p>Thank you for reading ❤️</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
