<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Neil Syiemlieh</title>
    <description>The latest articles on DEV Community by Neil Syiemlieh (@mebble).</description>
    <link>https://dev.to/mebble</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F109307%2F009ccb31-a27e-46a0-bd51-5ff907f2b41a.jpeg</url>
      <title>DEV Community: Neil Syiemlieh</title>
      <link>https://dev.to/mebble</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mebble"/>
    <language>en</language>
    <item>
      <title>ltag: A little CLI tool for tagged text searching</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Fri, 27 Oct 2023 15:14:40 +0000</pubDate>
      <link>https://dev.to/mebble/ltag-a-little-cli-tool-for-tagged-text-searching-31o3</link>
      <guid>https://dev.to/mebble/ltag-a-little-cli-tool-for-tagged-text-searching-31o3</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I have a command reference. It's a text file with lots of CLI commands I've written down because I don't want to memorise them all. For example here's a bunch of network-related commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nslookup -type=ns example.com
nslookup -type=txt example.com
nslookup -type=cname example.com
nslookup example.com 1.1.1.1
dig example.com txt
dig example.com cname
netstat --tcp
netstat --program
netstat --listening
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I want to look up a command, I don't always remember the actual command I want. Let's suppose I need to do a DNS lookup. I might not remember that I need &lt;code&gt;dig&lt;/code&gt; or &lt;code&gt;nslookup&lt;/code&gt;. Or I might just need something to do with networking. How can I search for all DNS commands or networking commands?&lt;/p&gt;

&lt;h2&gt;
  
  
  Halfway There: A Better Command Reference
&lt;/h2&gt;

&lt;p&gt;I can add headings and sub-headings to the list above. Each heading starts with a hashtag to differentiate it from the actual commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Networking
# DNS
nslookup -type=ns example.com
nslookup -type=txt example.com
nslookup -type=cname example.com
nslookup example.com 1.1.1.1
dig example.com txt
dig example.com cname
# See processes and ports used
netstat --tcp
netstat --program
netstat --listening
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is better, but I'd still need to search for DNS and scan over the following lines to find the command I want. &lt;strong&gt;A better way is to associate a bunch of tags with each line. Each tag would place the line in some category. A DNS category, a networking category.&lt;/strong&gt; But manually writing "#dns" after every DNS command in my list would be tedious. It would also pollute the command reference with tags everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: ltag + fzf
&lt;/h2&gt;

&lt;p&gt;So instead I created a tool read the above text, append the heading to every line as a tag, and print out the result. That would convert the above text to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nslookup -type=ns example.com #networking #dns
nslookup -type=txt example.com #networking #dns
nslookup -type=cname example.com #networking #dns
nslookup example.com 1.1.1.1 #networking #dns
dig example.com txt #networking #dns
dig example.com cname #networking #dns
netstat --tcp #networking #see-processes-and-ports-used
netstat --program #networking #see-processes-and-ports-used
netstat --listening #networking #see-processes-and-ports-used
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I call this tool "ltag", short for "Line tag". It's written in Go. Here's the git repository: &lt;a href="https://github.com/mebble/ltag/"&gt;mebble/ltag&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With tagging out of the way, I now have the ability to search.&lt;/p&gt;

&lt;p&gt;The CLI search tool I use is &lt;a href="https://github.com/junegunn/fzf"&gt;fzf&lt;/a&gt;. fzf takes in any text stream and spins up a TUI for you to fuzzy search through the text. I can pipe my tool's output to fzf and violà, I can now search by command and by tag!&lt;/p&gt;

&lt;p&gt;I still have one problem though. The purpose of looking up commands is so that I can run them. When I select a command through fzf, the tags associated with that command also get selected. I'd like to get rid of these tags once I've found the command I want. So my tool is also able to remove tags from the selected line.&lt;/p&gt;

&lt;p&gt;I can now do a quick command lookup using a shell alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;cl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cat ~/.cmd-reference.txt | ltag | fzf | ltag --trim | pbcopy"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Beyond a Command Reference
&lt;/h2&gt;

&lt;p&gt;This tool could help you search through any list of things. And the list doesn't have to be in a text file. ltag reads from standard input, so you can pipe the output of any command to it.&lt;/p&gt;

&lt;p&gt;This is my first Go project, and I'm glad I found a way to create something actually useful. So here it is, hope you find it useful as well.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>go</category>
      <category>cli</category>
      <category>fzf</category>
    </item>
    <item>
      <title>Sirup: A CLI tool to manage your local Git repositories</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Fri, 18 Feb 2022 09:36:35 +0000</pubDate>
      <link>https://dev.to/mebble/sirup-a-cli-tool-to-manage-your-local-git-repositories-4k2</link>
      <guid>https://dev.to/mebble/sirup-a-cli-tool-to-manage-your-local-git-repositories-4k2</guid>
      <description>&lt;p&gt;Hey guys I made a CLI tool that might help you if you have a lot of git repositories in your computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I recently got a new laptop which meant I had to move the 100+ repos I had in my old laptop. I couldn't simply move or copy all the repos because my old laptop was really slow. I thought I might as well just push all the repos to their remotes and then clone them from my new laptop, but then I realised it would be really tedious to &lt;code&gt;cd&lt;/code&gt; into each one of the repos, figure out which repo is clean or dirty, which repo is synced to its remote, and so on. So I decided to create a script to help me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter &lt;code&gt;sirup&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;sirup&lt;/code&gt; will show you a JSON summary of all your git repositories. You could analyse the JSON using any standard tool to figure out the status of each repo. This helps you know which repos will need to be cleaned up. I personally like to use the interactive Node.js shell for this. Then you could move this JSON to another computer and generate the git repositories over there. In the process, you could also tweak this JSON so that in your destination computer, &lt;code&gt;sirup&lt;/code&gt; would pick up these tweaks and behave accordingly.&lt;/p&gt;

&lt;p&gt;Here's the project on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mebble"&gt;
        mebble
      &lt;/a&gt; / &lt;a href="https://github.com/mebble/sirup"&gt;
        sirup
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A CLI tool for migrating your git repositories
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1 id="user-content-sirup"&gt;&lt;a class="heading-link" href="https://github.com/mebble/sirup#sirup"&gt;sirup&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Summarise a directory of git repos. Regenerate them from the summary.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#requirements"&gt;Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mebble/sirup#installation"&gt;Installation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#install-and-update"&gt;Install and update&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#remove"&gt;Remove&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#usage"&gt;Usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mebble/sirup#examples"&gt;Examples&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mebble/sirup#sirup-sum"&gt;sirup sum&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#recipes"&gt;Recipes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#sirup-gen"&gt;sirup gen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#who-needs-this"&gt;Who Needs This?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mebble/sirup#development"&gt;Development&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mebble/sirup#testing"&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="user-content-requirements"&gt;&lt;a class="heading-link" href="https://github.com/mebble/sirup#requirements"&gt;Requirements&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Python 3 at &lt;code&gt;/usr/bin/python3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Git 2.22 or above&lt;/li&gt;
&lt;li&gt;Ensure that &lt;code&gt;~/.local/bin/&lt;/code&gt; is in your &lt;code&gt;$PATH&lt;/code&gt; environment variable&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stedolan.github.io/jq/" rel="nofollow"&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt; (optional) so you can use some handy recipes shown below&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="user-content-installation"&gt;&lt;a class="heading-link" href="https://github.com/mebble/sirup#installation"&gt;Installation&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="user-content-install-and-update"&gt;&lt;a class="heading-link" href="https://github.com/mebble/sirup#install-and-update"&gt;Install and update&lt;/a&gt;&lt;/h3&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/mebble/sirup/main/scripts/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="user-content-remove"&gt;&lt;a class="heading-link" href="https://github.com/mebble/sirup#remove"&gt;Remove&lt;/a&gt;&lt;/h3&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/mebble/sirup/main/scripts/remove.sh | sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="user-content-usage"&gt;&lt;a class="heading-link" href="https://github.com/mebble/sirup#usage"&gt;Usage&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Print the usage instructions by running:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;sirup help
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;Usage: sirup &amp;lt;command&amp;gt; &amp;lt;args&amp;amp;gt
Commands
    help                        Print these usage instructions
    sum                         Summarise git repos and print the summary in JSON to stdout
        --repos ./repos/dir     The directory containing the git repos
        --log   [optional]      Will output logs to stdout
    gen                         Generate git repos from a summary file
        --from  ./sum/file      Path to the summary file
        --to    ./dest/dir      The destination directory where you want&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mebble/sirup"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Hope this helps anyone who runs into a similar situation.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>python</category>
      <category>git</category>
      <category>cli</category>
    </item>
    <item>
      <title>Game of Life with p5 and Svelte</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Wed, 26 May 2021 05:44:40 +0000</pubDate>
      <link>https://dev.to/mebble/game-of-life-with-p5-and-svelte-3j6k</link>
      <guid>https://dev.to/mebble/game-of-life-with-p5-and-svelte-3j6k</guid>
      <description>&lt;p&gt;Made a little web app over the last couple of days of Conway's Game Of Life. It uses TypeScript for the algorithm, Svelte for the web app stuff, and p5.js for rendering cells in a canvas element. Hope you find it interesting!&lt;/p&gt;

&lt;p&gt;Check it out over at: &lt;a href="https://cgof.netlify.app/"&gt;cgof.netlify.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cwAnR2Y7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwx14l37d25ylqdolrn2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cwAnR2Y7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwx14l37d25ylqdolrn2.png" alt="Alt Text" width="425" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
    </item>
    <item>
      <title>bURL: A tiny web app for breaking down URLs</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Mon, 19 Apr 2021 16:01:20 +0000</pubDate>
      <link>https://dev.to/mebble/burl-a-tiny-web-app-for-breaking-down-urls-3nen</link>
      <guid>https://dev.to/mebble/burl-a-tiny-web-app-for-breaking-down-urls-3nen</guid>
      <description>&lt;p&gt;I've been building a little web app that would help you edit URLs more seamlessly. It gives you a breakdown of a URL so you could easily manipulate it. Here's the MVP version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GwMSYUCg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/burl/burl-sample-reddit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GwMSYUCg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/burl/burl-sample-reddit.png" alt="App screenshot showing how it works with a URL to a Reddit post" width="456" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check it out at &lt;a href="https://burl.bar/"&gt;burl.bar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's still an MVP at this point. I'm putting it out there now so I get feedback as I'm building it. Gonna spend the next couple of weeks prettying it up and putting in more features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Did I Make This?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reason One: Managing Permalinks
&lt;/h3&gt;

&lt;p&gt;Some time ago I had to work with Grafana dashboards. I needed to work with permalinks to the dashboards that would encode a specific dashboard state. I needed to edit parts of the dashboard state like the time range using the "from" and "to" query parameters, and the dashboard refresh rate using the "refresh" parameter. A typical permalink would hence look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://mydashboard.com/dashboard/service-metrics?orgId=101&amp;amp;from=now-6h&amp;amp;to=now&amp;amp;refresh=30s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It's possible to manually edit this if you need to, but if there are many more URLs and more query parameters involved, it gets tedious.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reason Two: Cleaning Up URLs
&lt;/h3&gt;

&lt;p&gt;When you share a post from social media by obtaining a link to that post, the link will typically include &lt;code&gt;utm_*&lt;/code&gt; query parameters so that the site could keep track of traffic to that post. I wanted an easy way to get rid of these parameters. Here's the URL used in the MVP screenshot above:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.reddit.com/r/aww/comments/mtv5a3/this_german_shepherd_is_well_known_in_her/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I thought it would be really nice if I could just click a couple of buttons to get rid of them.&lt;/p&gt;

&lt;p&gt;So I decided to build a tool that would fulfil both the use cases above and any new use cases one could come up with!&lt;/p&gt;
&lt;h2&gt;
  
  
  Updates
&lt;/h2&gt;

&lt;p&gt;I'll be posting updates once or twice a week on &lt;a href="https://twitter.com/leesonHere"&gt;my Twitter&lt;/a&gt; so you can follow me there for updates. I've posted two so far and I'm hoping for some good progress ahead.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1383705756407533569-160" src="https://platform.twitter.com/embed/Tweet.html?id=1383705756407533569"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1383705756407533569-160');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1383705756407533569&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The repository is public. I'm open to any PRs, although I haven't been able to afford time to flesh out a contribution guide. But any kind of PRs/issues are welcome!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mebble"&gt;
        mebble
      &lt;/a&gt; / &lt;a href="https://github.com/mebble/burl"&gt;
        burl
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Breaking URLs
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1 id="user-content-burl"&gt;&lt;a class="heading-link" href="https://github.com/mebble/burl#burl"&gt;bURL&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.com/mebble/burl/actions"&gt;&lt;img src="https://github.com/mebble/burl/workflows/CI/badge.svg" alt="CI Status"&gt;&lt;/a&gt;
&lt;a href="https://app.netlify.com/sites/burl/deploys" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/1abff9cd8a67cafedfc028cf3cd3e372b58512acb038b2e2b8db1dfd4f332199/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f63353963346661322d363465342d343665382d613064632d6562643037383936343735622f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Break up URLs at &lt;a href="https://burl.netlify.app/" rel="nofollow"&gt;burl.netlify.app&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="user-content-usage"&gt;&lt;a class="heading-link" href="https://github.com/mebble/burl#usage"&gt;Usage&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Open the app with a blank URL:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://burl.netlify.app/" rel="nofollow"&gt;https://burl.netlify.app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Open the app with some given URL:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://burl.netlify.app/?u=https://www.reddit.com/r/aww/comments/mtv5a3/this_german_shepherd_is_well_known_in_her/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3" rel="nofollow"&gt;https://burl.netlify.app/?u=https://www.reddit.com/r/aww/comments/mtv5a3/this_german_shepherd_is_well_known_in_her/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="user-content-dev-requirements"&gt;&lt;a class="heading-link" href="https://github.com/mebble/burl#dev-requirements"&gt;Dev Requirements&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;yarn&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="user-content-dev-setup"&gt;&lt;a class="heading-link" href="https://github.com/mebble/burl#dev-setup"&gt;Dev Setup&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Clone the project, &lt;code&gt;cd&lt;/code&gt; into the project's root directory and install the project's dependencies&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c1"&gt;cd&lt;/span&gt; burl
yarn install&lt;/pre&gt;

&lt;/div&gt;
&lt;h2 id="user-content-testing"&gt;&lt;a class="heading-link" href="https://github.com/mebble/burl#testing"&gt;Testing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run the application in development mode&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;yarn dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In another terminal window, open the Cypress runner&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;yarn cypress:open&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In the Cypress runner, select the test file you want to run. This test will be run in a Cypress-controlled browser. Then as you update your tests and the corresponding application code, you can re-run the tests from the Cypress browser.&lt;/p&gt;
&lt;p&gt;You can also run the Cypress tests in headless mode:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;yarn cypress:run&lt;/pre&gt;

&lt;/div&gt;
&lt;h2 id="user-content-references"&gt;&lt;a class="heading-link" href="https://github.com/mebble/burl#references"&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;URL structure: &lt;a href="https://en.wikipedia.org/wiki/URL#Syntax" rel="nofollow"&gt;https://en.wikipedia.org/wiki/URL#Syntax&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;URL encoding: &lt;a href="https://en.wikipedia.org/wiki/Percent-encoding" rel="nofollow"&gt;https://en.wikipedia.org/wiki/Percent-encoding&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;URI schemes: &lt;a href="https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml" rel="nofollow"&gt;https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mebble/burl"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Plans
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pretty UI
&lt;/h3&gt;

&lt;p&gt;I'm thinking of quickly patching up the UI using a React component library like &lt;a href="https://ant.design/docs/react/introduce"&gt;Ant Design&lt;/a&gt; or &lt;a href="https://react-bootstrap.github.io/"&gt;React Bootstrap&lt;/a&gt;. Then later we could go completely custom by using our own CSS. For CSS in a React app, I think a CSS-in-JS solution provides a good dev experience. So I'm thinking &lt;a href="https://styled-components.com/"&gt;styled-components&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shareability
&lt;/h3&gt;

&lt;p&gt;I want the app state to be shareable. If two people have to manipulate URLs for some reason, and they wanna share a broken-down view of a URL to one another, it should be as easy as sharing a link. So if you wanna share the broken-down Reddit post link to someone, you just prepend &lt;code&gt;burl.bar?u=&lt;/code&gt; to it and you're good to go:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This isn't implemented, so the following URL won't work &lt;strong&gt;yet&lt;/strong&gt;.&lt;/em&gt;&lt;br&gt;
Update: It works now!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://burl.bar?u=https://www.reddit.com/r/aww/comments/mtv5a3/this_german_shepherd_is_well_known_in_her/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3"&gt;burl.bar?u=https://www.reddit.com/r/aww/comments/mtv5a3/this_german_shepherd_is_well_known_in_her/?utm_source=share&amp;amp;utm_medium=web2x&amp;amp;context=3&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Many URL Formats
&lt;/h3&gt;

&lt;p&gt;For now, the app supports only http and https URLs. I'm imagining it would later support other URL protocols as well, such as ssh, ftp, etc. The URL breakdown input fields would be based on the protocol of the URL input.&lt;/p&gt;

&lt;p&gt;This tool has already come in handy to me since building the basic version. It might help you out someday too! Thanks for reading.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Event Streams for Reactive Views</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Tue, 23 Feb 2021 08:17:29 +0000</pubDate>
      <link>https://dev.to/mebble/event-streams-for-reactive-views-134o</link>
      <guid>https://dev.to/mebble/event-streams-for-reactive-views-134o</guid>
      <description>&lt;p&gt;I remember hearing about Bacon.js one day and checking out their &lt;a href="https://baconjs.github.io/"&gt;Getting Started page&lt;/a&gt;. In it, they demonstrate a counter using the Bacon event streaming library. This is the demo code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bacon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bacon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="c1"&gt;// map up to 1, down to -1&lt;/span&gt;
  &lt;span class="nx"&gt;up&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;down&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="c1"&gt;// accumulate sum&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// assign observable value to jQuery property text&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well this was something very new to me. In my early days of programming, when using jQuery or vanilla JS with the DOM API, I would manually update the view whenever my state changed. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;updateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;updateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#up-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;updateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#down-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;updateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then when I heard that frameworks such as React would update the view for me, I thought "Great! One less thing to think about!". My code became something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Up&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Down&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ooooh it's declarative. No more fragile imperative logic, right? One less thing to think about! Now I've got less code, which means less clutter and possibly fewer bugs. And now there's no way I might accidentally forget to update my view! I just need to write to the state, and the state would write to the view for me!&lt;/p&gt;

&lt;h2&gt;
  
  
  Events, State, View
&lt;/h2&gt;

&lt;p&gt;Writing to the state is triggered by the user clicking a button. A user clicking a button is an event. In UI code, we get a lot of events. From the user, from the network, from some background task. With these events we decide if and how we write to the state. Then the state shows us what's changed by updating the view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QnepS9xW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/event-stream-view/event-state-view.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QnepS9xW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/event-stream-view/event-state-view.jpg" alt="Events triggering writes to the state, and the state automatically updating the view" width="631" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is great. Now we can focus on state management. In many apps, state management is simple enough. If it gets complex, you can try out an event sourcing-ish tool like &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt; or a state machine tool like &lt;a href="https://xstate.js.org/"&gt;XState&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Events, Transform, Accumulate, View
&lt;/h2&gt;

&lt;p&gt;But it never occurred to me that state management isn't &lt;em&gt;a must&lt;/em&gt;. State management seemed like such a smarty pants thing to do, I never asked if you could maybe wire up your view to your events &lt;em&gt;directly&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Get an event, write to the view.&lt;/p&gt;

&lt;p&gt;Of course this alone is very limiting. We should be able to transform the event. Remember old events. Process two or three different events to get a single result. Merge and accumulate events. Ignore events that don't matter. If we could do all this, we get all the power we had with state management, without actually doing state management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Sides, Same Coin
&lt;/h2&gt;

&lt;p&gt;My mind was blown when I realised that state management is basically the same darn thing. When you write to the state, you are doing all event-related processing in one go. When your &lt;code&gt;#up-button&lt;/code&gt; and &lt;code&gt;#down-button&lt;/code&gt; are clicked, they're equivalent to two emitted events, emitted on their own event streams. When they write to the state (i.e. &lt;code&gt;count++&lt;/code&gt; and &lt;code&gt;count--&lt;/code&gt;), that's equivalent to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;merging their streams&lt;/li&gt;
&lt;li&gt;defining how that merge would affect the events that came before them i.e. it's accumulating them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So the state is like a bucket where you dump all your event-processed results. In the event processing world, the ability to accumulate all events that have happened is equivalent to storing state. &lt;strong&gt;Because that's what state is: the state of something after everything that's happened to it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that's how I understood what Bacon.js meant when it said:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bacon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bacon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="c1"&gt;// map up to 1, down to -1&lt;/span&gt;
  &lt;span class="nx"&gt;up&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;down&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="c1"&gt;// accumulate sum&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// assign observable value to jQuery property text&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3agriFGV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/event-stream-view/event-view.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3agriFGV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/event-stream-view/event-view.jpg" alt="Events being transformed, event streams merged and events being accumulated, and the result being used to update the view" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how we manage a &lt;code&gt;count&lt;/code&gt; state in the event-streaming world. State management and event stream processing are two sides of the same coin. You can use either, depending on your requirements. These two paradigms are object-oriented programming's approach and functional programming's approach to the same problem, respectively.&lt;/p&gt;

&lt;p&gt;A very popular event stream processing library is &lt;a href="https://rxjs-dev.firebaseapp.com/"&gt;RxJS&lt;/a&gt;. Their site includes a pretty &lt;a href="https://rxjs-dev.firebaseapp.com/guide/overview"&gt;good guide&lt;/a&gt; into this style of programming. There's also &lt;a href="https://rxmarbles.com/#merge"&gt;rxmarbles&lt;/a&gt;, which has interactive diagrams of Rx event streams. I think these are good starting points if you're new to this and want to dive deeper.&lt;/p&gt;

&lt;p&gt;Have a nice evening.&lt;/p&gt;




&lt;p&gt;If you liked this post, consider &lt;a href="https://mebble.town/posts/event-stream-view?utm_source=dev-to"&gt;viewing it on my site&lt;/a&gt;! You'll see other posts I've made and you'll find notes where I document my learnings too!&lt;/p&gt;

</description>
      <category>events</category>
      <category>state</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A QR Code Primer</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Sat, 20 Feb 2021 09:33:40 +0000</pubDate>
      <link>https://dev.to/mebble/a-qr-code-primer-5f4p</link>
      <guid>https://dev.to/mebble/a-qr-code-primer-5f4p</guid>
      <description>&lt;p&gt;You're probably familiar with the QR (Quick Response) Code. Those little boxes of even littler black and white boxes. You've mostly used them to make payments. You've maybe even used one to add someone's contacts to your phone or to follow someone on social media. But what exactly are they?&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Just an ID
&lt;/h2&gt;

&lt;p&gt;For the longest time, I had thought that a QR Code was some unique combination of black and white squares like some sort of ID. That a QR Code is meant to be just one of a bazillion possible codes. That no other code like the one you're looking at exists. I had assumed that if you wanted a QR Code for yourself, you'd have to get one registered, like how you would get your own unique vehicle number plate registered. I've only recently learnt that it's not the point of a QR Code. A QR Code is unique in the same way that a random piece of text you'd note down on a piece of paper would be unique. So a QR Code is just written text, written in a form that's readable by a computer. You also &lt;a href="https://www.qrcode.com/en/faq.html#patentH2Title"&gt;don't have to get one registered&lt;/a&gt;; you can easily generate QR Codes that contain any content you want. Ever since I learnt this, I've played around with QR Codes a bit and I'd like to write about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Playing With Codes
&lt;/h2&gt;

&lt;p&gt;If you scan a code using any of your payment apps, they attempt to make a payment. The QR scanner on your social media apps might attempt to follow a person. They don't show you what content is in the code. Therefore, you need a generic QR scanner app that makes no assumptions about the QR Code's intent. It should just scan the code and show you the contents encoded within. And there are two such apps that you likely already have: Google Lens on Android and the iOS camera app on the iPhone (&lt;a href="https://web.archive.org/web/20190105172332/https://www.cultofmac.com/485380/how-to-scan-qr-codes-iphone/"&gt;iOS 11 and higher&lt;/a&gt;). These apps are a great way to demonstrate just the interpretation of the QR Code.&lt;/p&gt;

&lt;p&gt;There are many websites that could generate a QR Code out of some content you provide. &lt;a href="https://www.the-qrcode-generator.com/"&gt;www.the-qrcode-generator.com&lt;/a&gt; is what we'll be using here. In the input box, you'll see a bunch of "data types" to pick from. These are the various formats that your QR Code's content could be in. Select the "Free Text" type to get the most freedom on what content you can put in. Let's put in the text "This is a QR code!".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g4pS-BFL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-generate-input-box-filled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g4pS-BFL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-generate-input-box-filled.png" alt="QR generator input box with a value of 'This is a QR code!'" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The generated code looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4HBwoXjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/sample-qr-code.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4HBwoXjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/sample-qr-code.png" alt="Generated QR Code of plaintext contents" width="452" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we scan the code using Google Lens, the app decodes it and shows us the contents!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9huucG7i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-plain.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9huucG7i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-plain.jpg" alt="Google Lens QR Code scanned response for plaintext contents" width="800" height="1290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's put in some different free text, but this time start it with a &lt;code&gt;tel:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0QFZzt3v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-tel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0QFZzt3v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-tel.png" alt="QR generator input box with a value of 'tel:123456789' and the generated QR Code" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we'll see that our scanner prompts us to make a call with this number.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UHcLrqJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-tel.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UHcLrqJs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-tel.jpg" alt="Google Lens QR Code scanned response for a telephone number" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Happening Here?
&lt;/h2&gt;

&lt;p&gt;Your QR Code scanner has to interpret the code in two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decode the QR Code to get the contents&lt;/li&gt;
&lt;li&gt;Decide what it should do based on the format of the contents (or whether it should do anything at all)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Decoding the QR Code
&lt;/h3&gt;

&lt;p&gt;This is the part where the QR Code technology comes in. "QR Code" is a registered trademark of DENSO WAVE INCORPORATED. They invented the QR Code. There's an &lt;a href="https://www.qrcode.com/en/"&gt;official site for it&lt;/a&gt; where they list out the features of a QR Code, the standards that have been refined over the years, etc. There's also an &lt;a href="https://www.iso.org/standard/62021.html"&gt;ISO standard for it&lt;/a&gt;. The standard defines the algorithm for encoding text into a QR Code and decoding the code back into text. It also defines the information required in the code like the QR version and error correction. All this information is encoded in dedicated parts of the QR Code. This &lt;a href="https://www.qr-code-generator.com/blog/how-does-a-qr-code-encode-data/"&gt;article gives us very succinct visuals&lt;/a&gt; that highlight these parts.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Parsing the contents
&lt;/h3&gt;

&lt;p&gt;Once the contents are decoded, the scanner now figures out what it's looking at based on its format. The format, or "data type" of the contents is not bound to the QR Code standards. We're now out of QR Code territory. This step is equivalent to typing out a piece of text and asking the computer what it's looking at. Is it a URL? A date? An email address? Or something else? There are quite a few standards that define these data types. A very popular list of data types is defined in the open-source &lt;a href="https://github.com/zxing/zxing"&gt;ZXing library&lt;/a&gt;. Stated in its README is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ZXing ("zebra crossing") is an open-source, multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Its wiki has a &lt;a href="https://github.com/zxing/zxing/wiki/Barcode-Contents"&gt;list of all the data types it recognises&lt;/a&gt; with some explanation for each one. I had found a link to it in this &lt;a href="https://stackoverflow.com/questions/19900835/qr-code-possible-data-types-or-standards"&gt;Stack Overflow thread&lt;/a&gt;, so I'm linking that thread here as well in case it helps you out.&lt;/p&gt;

&lt;p&gt;In our little experiment above, we encoded the text &lt;code&gt;This is a QR code!&lt;/code&gt; and &lt;code&gt;tel:123456789&lt;/code&gt;. The first one doesn't follow any certain format, so Google Lens simply showed it back to us. The second one follows the &lt;a href="https://github.com/zxing/zxing/wiki/Barcode-Contents#telephone-numbers"&gt;telephone numbers format&lt;/a&gt; and since Google Lens recognises this format, it prompted us to perform some action with this phone number. Notice that if we were to omit the &lt;code&gt;tel:&lt;/code&gt; at the beginning of the phone number, Google Lens would see it as just plain text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UtEinsJc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-tel-text.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UtEinsJc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-tel-text.jpg" alt="Google Lens QR Code scanned response for a plain-text number" width="800" height="1277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The format most commonly used in QR Codes is the URL. A URL works great because it's short, it can link to literally any web content (or even app content), and the only user action required to use it is a single click. This works great for restaurant menus or ad campaigns. Your phone's operating system could also decide if it should open the URL directly in the appropriate app. This lets you do things like encode a Google Maps link to a specific location and let the user open it directly in the Google Maps app.&lt;/p&gt;

&lt;p&gt;A pretty interesting format though is the &lt;a href="https://github.com/zxing/zxing/wiki/Barcode-Contents#contact-information"&gt;MECARD format for describing a person's contact information&lt;/a&gt;. Let's put in the sample text that they provided in that page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MECARD:N:Owen,Sean;ADR:76 9th Avenue, 4th Floor, New York, NY 10011;TEL:12125551212;EMAIL:srowen@example.com;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GVcsk9CM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-contact.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GVcsk9CM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-contact.png" alt="QR generator input box with contact information and the generated QR Code" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and Google Lens reads this as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IPApft6q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-contact.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IPApft6q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/qr-code-response-contact.jpg" alt="Google Lens QR Code scanned response for contact information" width="800" height="1377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to demonstrate these different formats using just the "Free Text" input of the QR Code generator on purpose. It's pretty clear now that the other input modes the generator gives you such as "Contact" are only meant to give you the convenience of not having to type out all that messy syntax yourself. Under the hood though, it's all just text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can They Have Emojis?
&lt;/h2&gt;

&lt;p&gt;In most cases, yes. But before we get into &lt;em&gt;how&lt;/em&gt; or &lt;em&gt;why&lt;/em&gt;, I need to be a little more honest about &lt;em&gt;what&lt;/em&gt; is in a QR Code. This section is concerned with step one of a QR Code: "Decoding the QR Code". It's about how we turn the 1s and 0s in a QR to the characters we see in the QR scanner's output.&lt;/p&gt;

&lt;p&gt;I mentioned in the previous section that the contents in a QR Code are "all just text". That's only part of the story. The reality is we can specify one of few "modes", aka the input character set of the contents we put in. Wikipedia has a &lt;a href="https://en.wikipedia.org/wiki/QR_code#Storage"&gt;list of the possible modes&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numeric only&lt;/li&gt;
&lt;li&gt;Alphanumeric&lt;/li&gt;
&lt;li&gt;Binary/byte&lt;/li&gt;
&lt;li&gt;Kanji/kana&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The QR specification says that when you create a QR in binary/byte mode, the character encoding is ISO 8859-1. What is a character encoding? It describes how we're supposed to turn the 1s and 0s into text. ISO 8859-1 is &lt;a href="https://kb.iu.edu/d/ahfr"&gt;basically ASCII, with some more characters put in&lt;/a&gt;. The QR generator we used seems to create the code in binary/byte mode by default. Hence, the scanner detects that the QR is in binary/byte mode and decodes the characters using ISO 8859-1. But ISO 8859-1 is just a small extension of ASCII. It doesn't describe how to turn 1s and 0s into emojis. So then how do QR scanners read emojis?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--d2wReTOC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-emoji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--d2wReTOC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-emoji.png" alt="QR generator input box with emojis and the generated QR Code" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turns out that in reality, many scanners will decode the QR Code using the UTF-8 character encoding by making use of an extension that the QR specificaton provides. Through this extension, a QR generator could provide a hint about the character encoding used. The &lt;a href="https://stackoverflow.com/questions/9699657/is-utf-8-the-encoding-of-choice-for-qr-codes-with-non-ascii-chars-by-now"&gt;answers on this StackOverflow post&lt;/a&gt; explain it well. So I guess our QR generator uses UTF-8 encoding through this extension, and this lets us use emojis in the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nonstandard Standards
&lt;/h2&gt;

&lt;p&gt;Since the format of the contents of a QR Code is independent of the QR Code itself, anybody can come up with their own format and still have a working QR Code. As long as they provide their users an application that could correctly interpret their custom format, there'll be no complaints. And that's exactly what happened. Over the years, as various companies, governments and organisations adopted the use of QR Codes in their applications, they came up with their own formats to meet their use cases. Some have decided to define a schema in a well established format like JSON or XML, while others have gone completely custom. Here's a short list of custom formats used in QR Codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Short_Payment_Descriptor"&gt;Short Payment Descriptor (SPAYD)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/EPC_QR_code"&gt;European Payments Council QR Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Mobile_deep_linking"&gt;Mobile deep linking&lt;/a&gt; formats on various mobile phone operating systems&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aspi-indonesia.or.id/qris/"&gt;QRIS&lt;/a&gt; by Bank Indonesia. A valid QRIS code can be found in the header image of &lt;a href="https://jakartaglobe.id/business/bank-indonesia-launches-qr-code-standard/"&gt;this news article&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;NPCI's &lt;a href="https://en.wikipedia.org/wiki/Unified_Payments_Interface"&gt;Unified Payments Interface&lt;/a&gt; (more on this below)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go ahead and scan the QR Codes shown in those pages, or copy and paste the sample contents into the QR Code generator. Chances are, your generic QR scanning app would not be able to parse the contents to prompt a user action, and so it would simply show the contents to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unified Payments Interface
&lt;/h2&gt;

&lt;p&gt;The Unified Payments Interface (UPI) is the official standard used to make payments across various payment platforms in India. If you're shopping in India and the shop you're in happens to accept payments through a QR Code, that QR Code is most likely UPI compliant. So naturally, I wanted to see what the UPI-formatted contents in a QR Code look like.&lt;/p&gt;

&lt;p&gt;If you scan a UPI QR Code near you using a generic QR scanner, you'll find that the decoded content is a &lt;a href="https://en.wikipedia.org/wiki/Mobile_deep_linking"&gt;deep link&lt;/a&gt; that contains the information necessary to make a UPI payment. Unfortunately I couldn't find any official documentation on the structure of this deep link. The closest I could get to some structured documentation was this &lt;a href="https://github.com/bgagan911/RandomDocs/wiki/NPCI-UPI---Specifications-for-Deep-Linking"&gt;wiki on GitHub&lt;/a&gt; which seems like the results of someone else's research on this same topic. In its most basic form, the UPI deep link looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upi://pay?pn=&amp;lt;payee-name&amp;gt;&amp;amp;pa=&amp;lt;payee-vpa&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a URL with a &lt;code&gt;upi&lt;/code&gt; scheme, a &lt;code&gt;pay&lt;/code&gt; user action and some parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pn&lt;/code&gt; the payee's name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pa&lt;/code&gt; the payee's &lt;a href="https://cleartax.in/s/vpa-virtual-payment-address"&gt;virtual payment address (VPA)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your QR Code scanner recognises URLs that don't start with &lt;code&gt;http&lt;/code&gt; or &lt;code&gt;https&lt;/code&gt;, the scanner might redirect you straight to the payment page of your default UPI compatible app. Google Lens doesn't seem to do this though.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://upiqr.in/"&gt;upiqr.in&lt;/a&gt; is a QR Code generator that will generator a UPI-compliant code given the payee's name and the payee's VPA. Again, all this does is it creates a UPI deep link from those two values and encodes the deep link into a QR Code using a QR Code standard. From this, we could tell that the payee's name and VPA satisfy the minimum required information needed to create a valid UPI deep link, and hence, a valid UPI QR Code.&lt;/p&gt;

&lt;p&gt;You can also create a UPI-compliant code by manually writing down the deep link in the &lt;a href="https://www.the-qrcode-generator.com/"&gt;www.the-qrcode-generator.com&lt;/a&gt; we used above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1s5m2Kd2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-upi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1s5m2Kd2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/input-and-qr-code-upi.png" alt="QR generator input box with UPI deep link and the generated QR Code" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter a valid VPA and you'll be able to make a payment through any UPI compatible app using your very own self-generated QR Code! Include the &lt;code&gt;cu&lt;/code&gt; and &lt;code&gt;am&lt;/code&gt; fields in the deep link and you've just created a QR Code that's bound to a specific amount of money!&lt;/p&gt;

&lt;h2&gt;
  
  
  Unanswered Questions
&lt;/h2&gt;

&lt;p&gt;While trying out different QR Code generators, there was something peculiar I noticed. Different QR generators generate different-looking codes for the same exact content. Here's the QR Code from above, the one with the content "This is a QR code!":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4HBwoXjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/sample-qr-code.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4HBwoXjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/sample-qr-code.png" alt="Generated QR Code of plaintext contents" width="452" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now check out this one with the same content, but from a different generator, &lt;a href="https://www.qr-code-generator.com/"&gt;www.qr-code-generator.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DRAzVJqI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/sample-qr-code-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DRAzVJqI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://mebble-town.s3.ap-south-1.amazonaws.com/posts/qr-codes/sample-qr-code-2.png" alt="Generated QR Code of plaintext contents from a different QR generator" width="312" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They clearly look different even though they store the same content! What gives? I'm guessing these generators use different values for parameters like the QR Code version, error correction level, etc. That could explain why they look different. Is there a QR scanner that could show us this metadata? That's something I haven't looked into yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspirations
&lt;/h2&gt;

&lt;p&gt;There two things I had found online a few months ago that inspired me to experiment with QR Codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A YouTube video on &lt;a href="https://www.youtube.com/watch?v=ExwqNreocpg"&gt;embedding an entire video game into a QR Code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A Twitter thread on &lt;a href="https://twitter.com/levelsio/status/1318890523743182851"&gt;using QR Code for restaurant menus&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1318890523743182851-906" src="https://platform.twitter.com/embed/Tweet.html?id=1318890523743182851"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1318890523743182851-906');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1318890523743182851&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Because any data (of a reasonable size) can be stored in a QR Code, the possible use cases seem endless. The official site lists the &lt;a href="https://www.qrcode.com/en/about/howtouse.html"&gt;many ways they can be used&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;If you're interested, check out &lt;a href="https://mebble.town/posts/qr-codes?utm_source=dev-to"&gt;this post at my website&lt;/a&gt;! It's new and gonna change quite a bit over time. I plan to post notes as well, where I would document my learnings in software and programming.&lt;/p&gt;

</description>
      <category>barcode</category>
      <category>qr</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What Can Array Folding Do?</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Sat, 20 Apr 2019 10:07:03 +0000</pubDate>
      <link>https://dev.to/mebble/what-can-array-folding-do-2k3n</link>
      <guid>https://dev.to/mebble/what-can-array-folding-do-2k3n</guid>
      <description>&lt;p&gt;This is Part 2 of the "Folds" series, where we look at how we could use the simple Fold pattern to perform a variety of array processing tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Was It Again?
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/mebble/learn-to-fold-your-js-arrays-2o8p"&gt;previous article&lt;/a&gt;, we looked at how the fold works under the hood. Let's see it again as a recap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It uses a &lt;code&gt;for..of&lt;/code&gt; loop to traverse the list &lt;code&gt;xs&lt;/code&gt;, reducing the list each time till we end up with just a single value. This programming pattern is very powerful. When I first learned about the fold, I was sceptical of how such a simple operation could do so much. But it turns out that a lot of problems in programming are reduction problems — we have a list of things and we want to extract a piece of information from that list.&lt;/p&gt;

&lt;p&gt;Many of you might be familiar with Python's built-in functions &lt;code&gt;sum&lt;/code&gt;, &lt;code&gt;len&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;. All these functions are essentially folds. I wanted to see how many more folds I could implement in JavaScript using just the function definition above. That would really demonstrate the various things this seemingly simple little function could accomplish. So below are different functions that we could create using the fold.&lt;/p&gt;
&lt;h2&gt;
  
  
  Keeping An Eye Out
&lt;/h2&gt;

&lt;p&gt;I want to mention that in each fold shown below, there are two parts worth looking out for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The reducer:&lt;/strong&gt; I've defined the reducer for each fold separately instead of inline, like the &lt;code&gt;add&lt;/code&gt; reducer for the &lt;code&gt;sum&lt;/code&gt; fold. The reducer is passed two arguments, &lt;code&gt;acc&lt;/code&gt; and &lt;code&gt;x&lt;/code&gt;. The data type of &lt;code&gt;acc&lt;/code&gt; would be that of its inital value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The initial value:&lt;/strong&gt; Notice how the initial value for every fold's accumulation is an identity with respect to the reducer. For example, &lt;code&gt;0&lt;/code&gt; is the initial value used in the &lt;code&gt;sum&lt;/code&gt; fold, because it is the identity under the &lt;code&gt;add&lt;/code&gt; reducer. Remember that from the point of view of the reducer, the accumulation's initial value should essentially hold zero information. It should be void and useless, like how &lt;code&gt;add&lt;/code&gt; sees &lt;code&gt;0&lt;/code&gt; as having no information.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Behold, The Folds
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;sum&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;sum(xs: number[]): number&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;sum&lt;/code&gt; is probably the very first thing you think about when asked about collecting a list of values into one.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;len&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;len(xs: any[]): number&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is an emulation of the universally loved &lt;code&gt;len&lt;/code&gt;, from Python. In the reducer, we ignore every element &lt;code&gt;x&lt;/code&gt;, just adding a &lt;code&gt;1&lt;/code&gt; instead.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;product&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;product(xs: number[]): number&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The product of a list of numbers. Having even a single &lt;code&gt;0&lt;/code&gt; in &lt;code&gt;xs&lt;/code&gt; would render this fold useless.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;join&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;join(xs: any[]): string&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;concat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;join&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will concatenate a list of strings, or a list of anything, really! Injecting &lt;code&gt;x&lt;/code&gt; into the template string invokes its &lt;code&gt;.toString()&lt;/code&gt; method. So me saying that the declaration is &lt;code&gt;join(xs: any[]): string&lt;/code&gt;, isn't specific enough. What I actually want is &lt;code&gt;xs&lt;/code&gt; to be of type &lt;code&gt;xs: A[]&lt;/code&gt; where &lt;code&gt;A&lt;/code&gt; is a data type that returns a nicely formatted string when we call its &lt;code&gt;.toString()&lt;/code&gt;. Without static typing, we can't do this in JavaScript. We see this feature in other languages though, like through &lt;a href="http://learnyouahaskell.com/types-and-typeclasses"&gt;Typeclasses in Haskell&lt;/a&gt; and &lt;a href="https://www.typescriptlang.org/docs/handbook/interfaces.html"&gt;Interfaces in TypeScript&lt;/a&gt;. Without it, JS would try to stringify &lt;code&gt;x&lt;/code&gt; the default way, which might not work so well for more complex objects.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;all&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;all(xs: boolean[]): boolean&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I really like how clean the &lt;code&gt;all&lt;/code&gt; and &lt;code&gt;some&lt;/code&gt; folds look. One problem though is that they don't do break out of the loop when the result becomes obvious. &lt;code&gt;all([false, true, true, true])&lt;/code&gt; will go through the entire list even though the result is known by the very first &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;some&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;some(xs: boolean[]): boolean&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;or&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;maximum&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;maximum(xs: number[]): number&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;maximum&lt;/code&gt; and &lt;code&gt;minimum&lt;/code&gt; could be used on an array of any orderable data type, like JavaScript strings. But then we'd have to use the appropriate initial value. The one we used here, &lt;code&gt;-Infinity&lt;/code&gt;, is only appropriate for an array of numbers.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;minimum&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;minimum(xs: number[]): number&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minimum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;flatten&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;flatten(xs: any[][]): any[]&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;concatArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flatten&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;concatArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This one has to be one of my favourites. There's a lot of array copying happening here. We could've mutated the &lt;code&gt;acc&lt;/code&gt; using &lt;code&gt;acc.push(...x)&lt;/code&gt; and returned it to avoid copying &lt;code&gt;acc&lt;/code&gt; all the time, but you gotta admit, the spread operator looks much cleaner. This flattens an array one level deep, just like Lodash's &lt;a href="https://lodash.com/docs/4.17.11#flatten"&gt;_.flatten&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;merge&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;merge(xs: object[]): object&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;combine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;merge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;combine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;merge&lt;/code&gt; is very similar to the &lt;code&gt;flatten&lt;/code&gt;, except it works on objects. It behaves just like JavaScript's built-in &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign"&gt;Object.assign&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;reverse(xs: any[]): any[]&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prepend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Another way we could've done this is mutate the &lt;code&gt;acc&lt;/code&gt; using &lt;code&gt;acc.unshift(x)&lt;/code&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift"&gt;MDN&lt;/a&gt;) and return it instead of copying it through the spread operator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; This fold's kind of an odd one out. Remember when I said that the accumulation's initial value was supposed to be an identity w.r.t. the reducer? Well, the one here, &lt;code&gt;[]&lt;/code&gt;, isn't. &lt;code&gt;prepend([], x)&lt;/code&gt; will return &lt;code&gt;[x]&lt;/code&gt;. According to Wikipedia's &lt;a href="https://en.wikipedia.org/wiki/Fold_(higher-order_function)#Special_folds_for_non-empty_lists"&gt;article&lt;/a&gt; on the fold:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One often wants to choose the &lt;em&gt;identity&lt;/em&gt; element of the operation f as the initial value z.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's no mention of a strict requirement for an identity element. So maybe &lt;em&gt;some&lt;/em&gt; elegant mathematical rules would have to be broken in our messy programming world. Or maybe I just did an oopsie somewhere.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;pipe&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;pipe(xs: { (x: any): any }[]): (x: any): any&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;composeR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;composeR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This one is my favourite. I might've butchered the type declaration for the pipe function here, so you'll have to forgive me. The thing I find interesting is initial value for the acc, &lt;code&gt;x =&amp;gt; x&lt;/code&gt;. It really drives home the idea that the initial value is an identity with respect to the reducer. As for the reducer, it is like the mathematical &lt;a href="https://en.wikipedia.org/wiki/Function_composition"&gt;function composition&lt;/a&gt;, except in reverse.&lt;/p&gt;

&lt;p&gt;The pipe takes in a list of unary functions and returns a function that runs them all in sequence. The returned value of each function is passed as the argument to the next.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;last&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;second&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I just found it fitting to put it at the end.&lt;/p&gt;
&lt;h2&gt;
  
  
  More Than Just A Fold
&lt;/h2&gt;

&lt;p&gt;All the examples we've seen so far are folds — they take a list of things and return just a single thing. These next ones are not exactly folds in the same sense, but we can still implement them using the fold. That's right, &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; can be made from the fold!&lt;/p&gt;

&lt;p&gt;They don't just require an &lt;code&gt;xs&lt;/code&gt; argument; they also need a function &lt;code&gt;f&lt;/code&gt;. So the reducer must be defined inline, so we could capture the &lt;code&gt;f&lt;/code&gt; through the reducer's closure. These examples also break the identity rule (see the &lt;code&gt;reverse&lt;/code&gt; section above).&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;map&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In both &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;, we pass in the function &lt;code&gt;f&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; &lt;code&gt;xs&lt;/code&gt;, making them "iteratee-first, data-last". This is so that we could leverage the power of &lt;a href="https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983"&gt;currying&lt;/a&gt; to make our code more modularized and composable.&lt;/p&gt;

&lt;p&gt;Again, we could've mutated the &lt;code&gt;acc&lt;/code&gt; using &lt;code&gt;acc.push&lt;/code&gt;, but where's the elegance in that? It would go against the principle of immutability that FP preaches. I'm kidding of course, these are all just experiments. In an actual piece of software, we don't really want to get &lt;em&gt;too&lt;/em&gt; functional in our own JS implementations, because JS isn't optimized for it (unless we absolutely know what we're doing). For that, we'd be better off using existing libraries like lodash/fp or Ramda.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Playground
&lt;/h2&gt;

&lt;p&gt;Every piece of code above has been included in this playground below. I also put in some examples of how we can use these folds together. A slight warning though: It looks very messy on a mobile screen.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    


  &lt;/code&gt;
  &lt;code&gt;
    
const fold = (reducer, init, xs) =&amp;gt; {
    let acc = init;
    for (const x of xs) {
        acc = reducer(acc, x);
    }
    return acc;
};

// reducers
const add = (acc, x) =&amp;gt; acc + x;
const inc = (acc, x) =&amp;gt; acc + 1;
const mult = (acc, x) =&amp;gt; acc * x;
const concat = (acc, x) =&amp;gt; `${acc}${x}`;
const and = (acc, x) =&amp;gt; acc &amp;amp;&amp;amp; x;
const or = (acc, x) =&amp;gt; acc || x;
const max = (acc, x) =&amp;gt; (x &amp;gt; acc) ? x : acc;
const min = (acc, x) =&amp;gt; (x &amp;lt; acc) ? x : acc;
const concatArray = (acc, x) =&amp;gt; [...acc, ...x];
const combine = (acc, x) =&amp;gt; ({ ...acc, ...x });
const prepend = (acc, x) =&amp;gt; [x, ...acc];
const composeR = (acc, x) =&amp;gt; {
    return m =&amp;gt; x(acc(m));
};
const second = (acc, x) =&amp;gt; x;

// folds
const sum = xs =&amp;gt; fold(add, 0, xs);
const len = xs =&amp;gt; fold(inc, 0, xs);
const product = xs =&amp;gt; fold(mult, 1, xs);
const join = xs =&amp;gt; fold(concat, '', xs);
const all = xs =&amp;gt; fold(and, true, xs);
const some = xs =&amp;gt; fold(or, false, xs);
const maximum = xs =&amp;gt; fold(max, -Infinity, xs);
const minimum = xs =&amp;gt; fold(min, Infinity, xs);
const flatten = xs =&amp;gt; fold(concatArray, [], xs);
const merge = xs =&amp;gt; fold(combine, {}, xs);
const reverse = xs =&amp;gt; fold(prepend, [], xs);
const pipe = xs =&amp;gt; fold(composeR, x =&amp;gt; x, xs);
const last = xs =&amp;gt; fold(second, null, xs);

// other things we could make through folding
const map = (f, xs) =&amp;gt; fold((acc, x) =&amp;gt; [...acc, f(x)], [], xs);
const filter = (f, xs) =&amp;gt; fold((acc, x) =&amp;gt; {
    return f(x)
        ? [...acc, x]
        : acc;
}, [], xs);

const A = [
    [0, 1],
    [2, 3, 7, 8],
    [9, 13],
    [16]
];

// find the sum of each row of A
b = map(sum, A);
console.log('b:', b);

// reverse each row of A and then flatten
c = flatten(map(reverse, A));
console.log('c:', c);

// get half of the absolute value of every number
const nums = [3, -8, 6, 23, -100, 8, 1];
d = map(pipe([Math.abs, x =&amp;gt; x / 2]), nums);
console.log('d:', d);

// filter out invalid words and make the remaining go UPPER!!
const words = ['cat', 'sl2k3', 'dog', 'sn@k3', 'bird'];
const validUpper = (ws) =&amp;gt; {
    const validWords = filter(w =&amp;gt; /^[a-z]+$/i.test(w), ws);
    const upper = map(x =&amp;gt; x.toUpperCase() + '!!', validWords);
    return upper;
};
e = validUpper(words);
console.log('e:', e);

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Like I said in my &lt;a href="https://dev.to/mebble/learn-to-fold-your-js-arrays-2o8p"&gt;previous post&lt;/a&gt;, our way of implementing the fold is a hack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're using a for-loop and reassigning the &lt;code&gt;acc&lt;/code&gt; variable, which isn't very respectful to the lords of immutability. We'll see how we could do that in the next article.&lt;/p&gt;

&lt;p&gt;A few of the ideas for this article were inspired by the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@zaid.naom/exploring-folds-a-powerful-pattern-of-functional-programming-3036974205c8"&gt;A Medium article on Folds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://learnyouahaskell.com/higher-order-functions#folds"&gt;The Folds section of Learn You a Haskell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>functional</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Learn To Fold Your JS Arrays</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Mon, 08 Apr 2019 11:45:05 +0000</pubDate>
      <link>https://dev.to/mebble/learn-to-fold-your-js-arrays-2o8p</link>
      <guid>https://dev.to/mebble/learn-to-fold-your-js-arrays-2o8p</guid>
      <description>&lt;p&gt;You might have come across a situation where you need to take an array of values and "collect" them. By this, I mean performing some operation on the array so we could obtain just a single value at the end. Below are a few examples.&lt;/p&gt;

&lt;p&gt;You've definitely had to sum up an array of numbers before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or get the product of an array of numbers:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;prod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or find the largest number in an array of numbers:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In each of these examples, we took an array of things and performed some operation that collected those things into a single thing.&lt;/p&gt;
&lt;h1&gt;
  
  
  What Is A Fold?
&lt;/h1&gt;

&lt;p&gt;The above examples have a few things in common. They all involve some very similar parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A place that holds the final result, commonly referred to as the accumulation or &lt;code&gt;acc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;An initial value for the accumulation (0, 1 and &lt;code&gt;-Infinity&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A binary operation that combines the accumulation and the array item we're currently working with (&lt;code&gt;add&lt;/code&gt;, &lt;code&gt;mult&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process of collecting items clearly follows a pattern. We're currently repeating a lot of code, so if we could abstract it into a function, we'd have code that's much cleaner and more expressive. There's a name for such a function, the Fold (&lt;a href="https://en.wikipedia.org/wiki/Fold_(higher-order_function)"&gt;Wikipedia&lt;/a&gt;). This function is one of the fundamentals of functional programming. What we're going to do is implement the fold ourselves in JS, because why not?&lt;/p&gt;
&lt;h2&gt;
  
  
  A Few Observations
&lt;/h2&gt;

&lt;p&gt;There are three things regarding the fold that are worth noting.&lt;/p&gt;

&lt;p&gt;The binary operations &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;mult&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; are called &lt;code&gt;reducers&lt;/code&gt;. A reducer takes two values—the current accumulation and the current array element—and returns the new accumulation.&lt;/p&gt;

&lt;p&gt;The initial value needs to be an &lt;code&gt;identity&lt;/code&gt; with respect to the reducer. This means when the initial value is passed to the reducer along with another value &lt;code&gt;x&lt;/code&gt;, the output is always &lt;code&gt;x&lt;/code&gt;. Examples:&lt;br&gt;
&lt;code&gt;add(0, x) = x&lt;/code&gt;&lt;br&gt;
&lt;code&gt;mult(1, x) = x&lt;/code&gt;&lt;br&gt;
&lt;code&gt;max(-Infinity, x) = x&lt;/code&gt;.&lt;br&gt;
Here, &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;-Infinity&lt;/code&gt; are identities with respect to the reducers &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;mult&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;, respectively. We need it to be an &lt;code&gt;identity&lt;/code&gt; because we want the initial accumulation to be "empty". &lt;code&gt;0&lt;/code&gt; is empty w.r.t. summation and &lt;code&gt;1&lt;/code&gt; is empty w.r.t. the product.&lt;/p&gt;

&lt;p&gt;All array elements must be of the same data type (say type &lt;code&gt;A&lt;/code&gt;), but the data type of the accumulation (say &lt;code&gt;B&lt;/code&gt;) doesn't have to be the same as the datatype of the array elements. As an example, this code folds an array of numbers into a string.&lt;br&gt;
&lt;/p&gt;
&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
// nothing

  &lt;/code&gt;
  &lt;code&gt;
    
const concatNum = (x, y) =&amp;gt; x + y.toString();  // concatenates a string x and number y
const numbers = [1, 2, 3, 4, 5];  // elements are of type number
let acc = '';  // accumulation is of type string
for (const num of numbers) {
    acc = concatNum(acc, num);
}
console.log(acc);

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Notice how the reducer's interface must be &lt;code&gt;reducer(acc: B, x: A): B&lt;/code&gt;, which in this case, was&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;concatNum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  Creating A Fold
&lt;/h1&gt;

&lt;p&gt;That was a lot of talk. Let's finally make the fold. The fold is a higher order function (I highly recommend &lt;a href="http://eloquentjavascript.net/05_higher_order.html#h_xxCc98lOBK"&gt;Eloquent Javascript&lt;/a&gt; for an HOF intro) that takes a reducer (a function), an initial value for the accumulation and an array (more formally a list, which is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Description"&gt;what JS arrays are&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We first generalise the add/mult/max reducer, calling it &lt;code&gt;reducer&lt;/code&gt; (surprise!). We'll call the inital value &lt;code&gt;init&lt;/code&gt;. We then generalise the array of things. It could be an array of anything, not just numbers, so we'll call it &lt;code&gt;xs&lt;/code&gt;. We've now defined the fold!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Do you notice the order of the arguments into the fold? There's a reason we first pass in &lt;code&gt;reducer&lt;/code&gt;, followed by &lt;code&gt;init&lt;/code&gt; and then &lt;code&gt;xs&lt;/code&gt;. It has something to do with &lt;a href="https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983"&gt;currying&lt;/a&gt;, which we'll get into some other time. The examples from above now look like this, fat arrow style:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Much better.&lt;/p&gt;

&lt;p&gt;We can write the reducers inline if we want:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maximum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here's an interactive editor for you to play with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
// nothing

  &lt;/code&gt;
  &lt;code&gt;
    
const fold = (reducer, init, xs) =&amp;gt; {
    let acc = init;
    for (const x of xs) {
        acc = reducer(acc, x);
    }
    return acc;
};

const sum = xs =&amp;gt; fold((acc, x) =&amp;gt; acc + x, 0, xs);
const prod = xs =&amp;gt; fold((acc, x) =&amp;gt; acc * x, 1, xs);
const maximum = xs =&amp;gt; fold((acc, x) =&amp;gt; (acc &amp;gt;= x) ? acc : x, -Infinity, xs);

const numbers = [3, 7, 1, 2, 5];
console.log('sum:', sum(numbers));
console.log('product:', prod(numbers));
console.log('maximum:', maximum(numbers));

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Pretty easy, right? Well, we kinda cheated. We used a for-loop (more specifically a for...of loop) in our fold definition, which is a big no-no in the functional programming world. Using a for-loop for data transformation means we're going to have to mutate some objects. Here, we mutated &lt;code&gt;acc&lt;/code&gt; by reassigning it in the loop. A real functional implementation of the fold would use recursion and would avoid mutation. We'll explore that in another article.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Few Notes For The Interested
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JS already has a fold, which is a method available on arrays. It's called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce"&gt;reduce&lt;/a&gt;. So I guess you could say re-implementing the fold ourselves was pretty pointless 🤷‍♂️ (although I hope it helps some FP newbie out there).&lt;/li&gt;
&lt;li&gt;Because we used a for...of loop instead of an ordinary for-loop, the fold we made works on more that just arrays—it works on any &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols"&gt;iterable object&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In general, the fold should work on any source of enumerable data, like lists and trees.&lt;/li&gt;
&lt;li&gt;The idea of "collecting" doesn't have to be about combining the array elements, like addition or multiplication. It could be about "find and replace", like max/min reducers, or about "applying sequentially", like a function application reducer to pipe functions (&lt;a href="http://learnyouahaskell.com/higher-order-functions#function-application"&gt;if you're interested&lt;/a&gt;). The applications are endless!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A function that takes a bunch of things to return just one thing might seem a little trivial, but we'll see how powerful it actually is by implementing many folds in the next article. We'll flatten arrays, pipe functions and [hopefully] do a lot more with the fold.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>functional</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Creating Image Filters in JS</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Fri, 29 Mar 2019 17:57:21 +0000</pubDate>
      <link>https://dev.to/mebble/image-processing-using-image-kernels-in-js-5550</link>
      <guid>https://dev.to/mebble/image-processing-using-image-kernels-in-js-5550</guid>
      <description>&lt;p&gt;I spent the last two weeks on a project that I hoped would help me obtain a concrete understanding of how image kernels work. You know those image filters you have in Photoshop or your typical photo editor app that let you sharpen or blur an image? Those are implemented using image kernels. This &lt;a href="http://setosa.io/ev/image-kernels/" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; has by far the best explanation of image kernels I could find. For something a little more formal, here's &lt;a href="https://en.wikipedia.org/wiki/Kernel_(image_processing)" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The demo is online and I've given the link to it below. What you'll see is a simple page with some instructions at the top. Feel free to play around with the kernel and sample images.&lt;/p&gt;

&lt;p&gt;The image is split into four partitions and each partition is passed to a web worker to be processed so we don't block the main thread. I found that four web workers are only a little over twice as fast as one web worker processing the entire image alone. I expected four times the speed, but I guess I got too optimistic, not considering the overhead in copying the pixel arrays, etc.&lt;/p&gt;

&lt;p&gt;I can conclude that I now do have a better understanding of how image kernels work (aside from the fact that I ended up spending way more time working with web workers). If only this could get me extra credit for my image processing course.&lt;/p&gt;

&lt;p&gt;Here's &lt;a href="https://mebble.github.io/imfx/" rel="noopener noreferrer"&gt;the demo&lt;/a&gt; and the repository:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mebble" rel="noopener noreferrer"&gt;
        mebble
      &lt;/a&gt; / &lt;a href="https://github.com/mebble/imfx" rel="noopener noreferrer"&gt;
        imfx
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Apply a filter to an image through kernel convolution
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;ImFx&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Perform client-side image processing algorithms like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spatial domain filtering&lt;/li&gt;
&lt;li&gt;Bit-plane slicing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check out &lt;a href="https://mebble.github.io/imfx/" rel="nofollow noopener noreferrer"&gt;the demo&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Takes an image&lt;/li&gt;
&lt;li&gt;Takes a kernel&lt;/li&gt;
&lt;li&gt;Applies kernel convolution on the image&lt;/li&gt;
&lt;li&gt;Displays the output&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it looks like&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mebble/imfxdocs/sharpen-kernel.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmebble%2Fimfxdocs%2Fsharpen-kernel.png" alt="Kernel for image sharpening"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The kernel for image sharpening&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mebble/imfxdocs/edge-kernel.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmebble%2Fimfxdocs%2Fedge-kernel.png" alt="Kernel for edge detection"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The kernel for edge detection&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mebble/imfxdocs/cat-example.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmebble%2Fimfxdocs%2Fcat-example.png" alt="Sharpening an image of a cat in a hat"&gt;&lt;/a&gt;
&lt;em&gt;Sharpening an image of a cat in a hat&lt;/em&gt; &lt;em&gt;(Source: &lt;a href="https://www.pexels.com/photo/grey-chartreaux-cat-with-red-and-white-party-hat-and-licking-nose-1663417/" rel="nofollow noopener noreferrer"&gt;Photo by rawpixel.com from Pexels&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/mebble/imfxdocs/bones-example.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmebble%2Fimfxdocs%2Fbones-example.png" alt="Edge Detection on an image of skeletons on the street"&gt;&lt;/a&gt;
&lt;em&gt;Edge Detection on an image of skeletons on the street&lt;/em&gt; &lt;em&gt;(Source: &lt;a href="https://www.pexels.com/photo/monochrome-photo-of-two-skeleton-wearing-hats-1599469/" rel="nofollow noopener noreferrer"&gt;Photo by Iván Rivero from Pexels&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;TODOs&lt;/h2&gt;

&lt;/div&gt;
&lt;ul class="contains-task-list"&gt;
&lt;li class="task-list-item"&gt;
 Choose updatable kernel from templates&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Choose from a selection of images&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Split and process image across 4 workers&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Log the time taken to process image. Can log the time taken separately for each worker&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Implement more image processing stuff
&lt;ul class="contains-task-list"&gt;
&lt;li class="task-list-item"&gt;
 min/max/median filters&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Separable filters for faster convolution&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Bit-plane slicing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Use WebGL for fast processing in each worker&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Upload image from device&lt;/li&gt;
&lt;li class="task-list-item"&gt;
 Take camera photo and use image&lt;/li&gt;
&lt;li class="task-list-item"&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mebble/imfx" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>multithreading</category>
    </item>
    <item>
      <title>Don't Make This Async/Await Oopsie!</title>
      <dc:creator>Neil Syiemlieh</dc:creator>
      <pubDate>Mon, 25 Mar 2019 15:00:00 +0000</pubDate>
      <link>https://dev.to/mebble/dont-make-this-asyncawait-mistake-1eao</link>
      <guid>https://dev.to/mebble/dont-make-this-asyncawait-mistake-1eao</guid>
      <description>&lt;p&gt;Suppose we need to perform some I/O on items of an array, like fetching the owners of cats from the cats' IDs using some API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catIDs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;132&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;345&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;243&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;423&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say we decide to use our newly acquired async/await skills to do the job. Async/await gets rid of the need for callbacks (in most cases), making asynchronous code look similar to synchronous code. But if we forget that we're still just dealing with asynchronous code, we might make a mistake that defeats the entire purpose of having concurrency.&lt;/p&gt;

&lt;p&gt;We might be tempted to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchOwners&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchCat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchOwner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ownerID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Was Our Oopsie? 🤷‍♂️
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: If you know what the oopsie was, then you probably already know what you're doing. You might know a use case for this behaviour, so I guess it's a little unfair to call it an "oopsie". This article is just to familiarise people with this async/await behaviour.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We run the code and all seems to be working alright. But there's a glaring problem in how we've used async/await. The problem is that we used &lt;code&gt;await&lt;/code&gt; within a for-loop. This problem is actually indicative of a common &lt;a href="https://en.m.wikipedia.org/wiki/Code_smell"&gt;code smell&lt;/a&gt;, which is the &lt;em&gt;"&lt;code&gt;.push&lt;/code&gt; to an output array within a for-loop"&lt;/em&gt; method of performing an array transformation, instead of using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;&lt;code&gt;.map&lt;/code&gt;&lt;/a&gt; (we'll get to this later).&lt;/p&gt;

&lt;p&gt;Because of the &lt;code&gt;await&lt;/code&gt; within the for-loop, the synchronous-looking &lt;code&gt;fetchOwners&lt;/code&gt; function is performing a fetch for the cats sequentially (kind of), instead of in parallel. The code &lt;code&gt;await&lt;/code&gt;s for the owner of one cat before moving on to the next for-loop iteration to fetch the owner of the next cat. Fetching the owner of one cat isn't dependent on any other cat, but we're acting like it is. So we're completely missing out on the ability to fetch the owners in parallel (oopsie! 🤷‍♂️).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; I mentioned "kind of" sequentially, because those sequential for-loop iterations are interleaved with other procedures (through the &lt;a href="https://youtu.be/8aGhZQkoFbQ"&gt;Event Loop&lt;/a&gt;), since the for-loop iterations &lt;code&gt;await&lt;/code&gt; within an &lt;code&gt;async&lt;/code&gt; function.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Should Be Doing 😎
&lt;/h2&gt;

&lt;p&gt;We shouldn't &lt;code&gt;await&lt;/code&gt; within a for-loop. In fact, this problem would be better off solved without a for-loop even if the code were synchronous. A &lt;code&gt;.map&lt;/code&gt; is the appropriate solution, because the problem we're dealing with is an array transformation, from an array of cat IDs to an array of owners.&lt;/p&gt;

&lt;p&gt;This is how we'd do it using &lt;code&gt;.map&lt;/code&gt; if the code were synchronous.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// catIDs -&amp;gt; owners&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetchCatSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetchOwnerSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ownerID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the code is actually asynchronous, we first need to transform an array of cat IDs to an array of promises (promises to the cats' owners) and then unpack that array of promises using &lt;code&gt;await&lt;/code&gt; to get the owners. This code doesn't handle rejected promises for the sake of simplicity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// catIDs -&amp;gt; ownerPromises -&amp;gt; owners&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchOwners&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ownerPromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fetchCat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fetchOwner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ownerID&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ownerPromises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To further flex our async/await skills, we could pass an &lt;code&gt;async&lt;/code&gt; callback to the map method and &lt;code&gt;await&lt;/code&gt; all intermediate responses (here, fetching a cat to get its owner's ID) within that callback. Remember, an &lt;code&gt;async&lt;/code&gt; function returns a promise, so we're still left with an array of promises as the output of &lt;code&gt;.map&lt;/code&gt;. This code is equivalent to the previous one, but without the ugly &lt;code&gt;.then&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchOwners&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ownerPromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;catIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchCat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchOwner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ownerID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ownerPromises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;owners&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is &lt;code&gt;.map&lt;/code&gt; actually doing?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;.map&lt;/code&gt; invokes the callback (in which we make an I/O request) on each cat ID sequentially. But since the callback returns a promise (or is an async function), &lt;code&gt;.map&lt;/code&gt; doesn't wait for the response for one cat to arrive before shooting off the request for the next cat.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The requests are shot &lt;em&gt;sequentially&lt;/em&gt;, but travel in &lt;em&gt;parallel&lt;/em&gt;, and their responses arrive out of order (imagine throwing a bunch of boomerangs with one hand behind your back).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we're now fetching the cat owners in parallel like we intended to 🙌! Oopsie undone!&lt;/p&gt;




&lt;p&gt;This was my very first post. Not just my first on DEV, but my first blog post ever. Hope you liked it.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>asyncawait</category>
      <category>async</category>
    </item>
  </channel>
</rss>
