<?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>Forem: Victor Cordova</title>
    <description>The latest articles on Forem by Victor Cordova (@victorandcode).</description>
    <link>https://forem.com/victorandcode</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%2F132301%2F9d7f853c-1024-4c20-a040-14689da292d3.jpeg</url>
      <title>Forem: Victor Cordova</title>
      <link>https://forem.com/victorandcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/victorandcode"/>
    <language>en</language>
    <item>
      <title>Learn your codebase and be 10x more effective</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Wed, 24 Jul 2024 10:04:46 +0000</pubDate>
      <link>https://forem.com/victorandcode/learn-your-codebase-and-be-10x-more-effective-4a4e</link>
      <guid>https://forem.com/victorandcode/learn-your-codebase-and-be-10x-more-effective-4a4e</guid>
      <description>&lt;p&gt;As a software engineer, being an expert on your team's/company's codebase is amongst the most important skills you can have. Here's why:&lt;/p&gt;

&lt;p&gt;Knowing your codebase lets you understand the costs and risks associated with any proposed changes. This means you can make more accurate estimates and prevent bugs. Also, you can help identify when's the right time to tackle some tech debt.&lt;/p&gt;

&lt;p&gt;Becoming familiar with a codebase takes time, but here are some methods I've used to make this process much faster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep a personal log&lt;/strong&gt;: of important files, coding patterns, and gotchas. Build it as you learn more.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speak to experts&lt;/strong&gt;: First, conduct a preliminary review of the code to identify patterns and questions. Then book a few short calls with experts in your company. If you don't know who they are, ask your manager. Make sure to ask them to point out any important documentation related to the code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use git smartly&lt;/strong&gt;: Read through past pull requests and see what files needed to be changed together. Use &lt;strong&gt;git blame&lt;/strong&gt; to see who wrote a particular line of code and reach out for additional context if possible. Use the git pickaxe to find when a particular line was added or removed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contribute to documentation&lt;/strong&gt;: If you find something that you deem important, discuss it with your team. Consider adding code comments explaining the reason for some technical decisions or using a wiki to document these decisions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identify and read past RFCs, design docs and ADRs&lt;/strong&gt;: Do this to understand why some decisions were made and what alternatives were considered.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Repeat as needed when you find a new part of the code you aren't familiar with.&lt;/p&gt;

&lt;p&gt;Thank you for reading! ⭐&lt;/p&gt;

&lt;p&gt;Also available on my personal blog &lt;a href="https://www.victorandcode.com/learn-your-codebase-and-be-10-x-more-effective" rel="noopener noreferrer"&gt;https://www.victorandcode.com/learn-your-codebase-and-be-10-x-more-effective&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pragmatism</category>
      <category>productivity</category>
      <category>onboarding</category>
    </item>
    <item>
      <title>12 Effective Writing Tips for Software Engineers</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Wed, 25 Jan 2023 12:30:00 +0000</pubDate>
      <link>https://forem.com/victorandcode/12-effective-writing-tips-for-software-engineers-21id</link>
      <guid>https://forem.com/victorandcode/12-effective-writing-tips-for-software-engineers-21id</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://www.victorandcode.com/12-effective-writing-tips-for-software-engineers?ref=devto" rel="noopener noreferrer"&gt;my personal blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Excellent written communication skills are key to your software engineering career growth. It can help you deliver projects more successfully, create better relationships at work, grow faster as an engineer, and much more. The more senior the role, the more you're expected to communicate with other humans. This article summarizes some lessons I've learned about communicating more efficiently in the context of software development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope 📒
&lt;/h2&gt;

&lt;p&gt;This article is mostly about written communication for &lt;strong&gt;software engineers&lt;/strong&gt; but it'll probably also be helpful for other roles working in the software development lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is effective communication 🤷
&lt;/h2&gt;

&lt;p&gt;First, let's define what I call "ineffective communication." It's an exchange of messages which has one or many of these characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow&lt;/li&gt;
&lt;li&gt;Frustrating&lt;/li&gt;
&lt;li&gt;Causes misunderstandings&lt;/li&gt;
&lt;li&gt;Consecutively makes people lose time and money&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By contrast, for the purpose of this article, effective communication leads to fast and empathetic resolution of problems and the exchange of ideas with a minimum number of misunderstandings.&lt;/p&gt;

&lt;h2&gt;
  
  
  List of communication tips ✍️
&lt;/h2&gt;

&lt;p&gt;
  &lt;u&gt;Know your audience&lt;/u&gt;: Before you send any message, ask the following.
  What's their role? What knowledge do they have in the topic you're about to
  discuss? What timezone are they in? All of this will help guide how technical
  your vocabulary will be. It's very different to say, "Our server's overloaded
  with requests, and we're working to fix the load balancer," than saying,
  "We're having some issues with our servers but are working on it."
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Have the key decision-makers in the conversation&lt;/u&gt;: If you don't, you
  might not receive essential feedback or need to backtrack on the decision
  afterward. Make sure to involve the right people but not anyone else.
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Be action-oriented, and propose solutions&lt;/u&gt;: Avoid conversations of the
  type: - Hey everyone, did you see we have this problem - Yup, we have a
  problem - The end
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Think about what follow-up questions the other person will ask&lt;/u&gt;: Try to
  answer them in advance, so the number of messages in the exchange is
  minimized.
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Use as few words as possible&lt;/u&gt;: If your message is short, more people
  will read it, it'll avoid confusion and it'll take less time to make a
  decision. So, before sending your message, review it. Delete as many words as
  you can to keep the core message and avoid any fluf
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Clearly state urgency and next steps&lt;/u&gt;: Say, if your question is urgent,
  what's the impact? Is it blocking anyone?
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Enumerate questions &lt;/u&gt;: For multiple questions, it's easier to enumerate
  them so you can refer back to them and allow the other person to answer one by
  one.
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;If there's room for interpretation clarify! &lt;/u&gt;: Believe it or not,
  &lt;b&gt;a lot of times&lt;/b&gt;, small assumptions or misunderstandings will be highly
  costly. If there's something with some room for interpretation or too vague,
  get to the details. The simplest way of doing this is to ask, "So when you say
  [insert original part of their message], you mean [shorter paraphrased
  version]?"
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Know when to change to videocall (or IRL conversation) &lt;/u&gt;: Remember,
  written communication has limits. If the conversation is taking too long or
  you need to discuss live changes, you might be better off having a call
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Think of solutions&lt;/u&gt;: Lead the conversation by saying "We have this
  problem, and I've thought about some implications, so I think we have these
  options enumerate options. What do you think?". Sooner or later, you'll be the
  person to whom people come for answers.
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Be kind &lt;/u&gt;: You're (probably) talking to a person. Don't demand things;
  ask nicely. Say hi, and present yourself if you're talking to someone for the
  first time; you don't have to send your whole life's story, just a simple "Hey
  name, I'm an engineer at team investigating an issue related to invoicing, I
  could really use your help with the following...".
&lt;/p&gt;

&lt;p&gt;
  &lt;u&gt;Respect people's attention&lt;/u&gt;: Messaging apps are built to distract people,
  so be mindful and don't @ everyone, don't @ after working hours.
&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;Thanks for reading this far. I hope one or many of these tips are as helpful to you as they have been to me.&lt;br&gt;
Again, communication is complex, but being a bit more thoughtful about what we write can go a long way.&lt;/p&gt;

</description>
      <category>softskills</category>
      <category>communication</category>
      <category>slack</category>
    </item>
    <item>
      <title>Understanding software estimates and how to get better at making them</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Sat, 19 Sep 2020 12:52:41 +0000</pubDate>
      <link>https://forem.com/victorandcode/understanding-software-estimates-and-how-to-get-better-at-making-them-3poe</link>
      <guid>https://forem.com/victorandcode/understanding-software-estimates-and-how-to-get-better-at-making-them-3poe</guid>
      <description>&lt;p&gt;The first time you finish a piece of software you've estimated, you discover a harsh reality ... software estimates are hard. Unexpected edge-cases, dependencies, meetings, and a thousand other things. This law summarizes it perfectly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;My objective with this post is to provide you with a framework to help you understand and create better software estimates, which will allow you to reduce risk in your projects and align expectations with other stakeholders.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a software estimate 🤷
&lt;/h2&gt;

&lt;p&gt;A software estimate predicts how much effort is necessary to create, modify, or maintain software. You give estimates in some unit, which in my experience is usually man-hours and story points.&lt;/p&gt;

&lt;p&gt;An estimate does NOT imply a commitment. &lt;strong&gt;It represents the most well-informed guess you can make with the given restrictions of time and knowledge&lt;/strong&gt;. This difference is often overlooked and can be the source of conflict and frustration. This doesn't mean you should not commit; it means you should treat estimation and commitment separately. As a professional, you should make a commitment when needed after carefully evaluating the situation, and preparing an estimate. &lt;strong&gt;But, you should also say NO when pressured to commit to work that isn't adequately estimated.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who needs estimates and why 📅
&lt;/h2&gt;

&lt;p&gt;It is crucial to understand how estimates fit into the bigger picture of your organization 💸. Estimates represent cost, which helps inform different stakeholders' decisions. Here are some common scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calculate the price of a project: Consultancy firms and freelancers use estimates to calculate how much they charge clients. For this reason, it is of critical importance that estimates are accurate.&lt;/li&gt;
&lt;li&gt;Defining product roadmaps: Product teams need to know how long a piece of software will take to shape their plans and help coordination.&lt;/li&gt;
&lt;li&gt;Sprint capacity planning: For teams working in sprints, estimates help scope a sprint and reach a sensible commitment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What makes estimating so hard 😟
&lt;/h2&gt;

&lt;p&gt;There are many reasons why doing estimates is so hard. This list presents what I believe are some of the most important ones you should take into account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communication is hard
&lt;/h3&gt;

&lt;p&gt;To develop software, you need to have conversations between people who are analyzing the problem and people who will design and create the software. During these conversations, information can be wrong, misunderstandings can happen, or data might lack documentation.&lt;br&gt;
It can take one big misunderstanding for an estimate to be dozens or hundreds of hours wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Every software is different
&lt;/h3&gt;

&lt;p&gt;It's almost impossible for a software that is more than a couple of code lines to be completely the same. They might be solving very similar needs (e.g., shopping cart), but they have been created by different people who chose other technologies at a different point in time, for a given market, with specific time constraints. All these decisions can drastically alter how much effort is needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scope creep
&lt;/h3&gt;

&lt;p&gt;Scope creep refers to unexpected changes that increase the scope initially planned for the project. It is natural that in a software project, you stumble upon an unexpected. Expect some changes to be asked, but mind that small things can pile up, so make sure that these changes are: discussed, negotiated, documented, and postponed (if possible).&lt;/p&gt;

&lt;h3&gt;
  
  
  Variations in experience and availability from the development team
&lt;/h3&gt;

&lt;p&gt;Some team members might lack experience with the technologies used in the project; this is not rare considering how technology advances. It's also possible that you don't know all these technologies in advance, which implies some learning time and occasional head bumps.&lt;/p&gt;

&lt;p&gt;The team's availability might also be unknown in advance. It would be best if you planned for holidays in advance to adjust the estimates. Unfortunately, things like resignations, lay-offs, and personal problems can happen without any warning.&lt;/p&gt;

&lt;h3&gt;
  
  
  The team's experience
&lt;/h3&gt;

&lt;p&gt;The team's experience can make all the difference between a good and a wrong estimate.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Technical expertise: An expert is more likely to know the patterns that will help implement the solution faster and will also be able to identify the risks more easily.&lt;/li&gt;
&lt;li&gt;Experience working together: People that have experience working together develop habits and processes that make them more productive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Who should do the estimate
&lt;/h3&gt;

&lt;p&gt;Ideally, the people doing the work should be doing the estimation. After all, they are the experts. If this is not possible, try to find someone with experience in similar projects and ask how much it took for them and what problems they found along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools and tips to improve your estimates 🧭
&lt;/h2&gt;

&lt;p&gt;These recommendations aren't set in stone, so I encourage you to adapt them to your team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Have the right mindset
&lt;/h3&gt;

&lt;p&gt;Acknowledge that software estimates are HARD (ask any software engineer ever). Even with all the information in the world, you are very likely to be wrong. However, also keep in mind that estimations do get better with experience. As an engineer, help other stakeholders understand this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clarify if you are doing a high-level estimate or a low-level one
&lt;/h3&gt;

&lt;p&gt;Knowing if you're doing a high-level or a low-level estimate will help select an estimation unit and guide how much time you spend going into details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Split the work
&lt;/h3&gt;

&lt;p&gt;Split it into smaller parts, especially when estimating big loads of work. This separation can be epics, features, screens, use-cases, user stories, or whatever you find comfortable. Even when estimating at a user-story level, you might later find that one of them is too big, so you can just split it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose the right unit of estimation and make sure everyone understands it
&lt;/h3&gt;

&lt;p&gt;I like &lt;a href="https://www.youtube.com/watch?v=eisuQefYw_o"&gt;Uncle Bob's&lt;/a&gt; advice around how estimates should never be a date but rather a date range. The cool thing is that you don't have to be working with dates to follow this advice. Whatever type of estimation you are doing, it's more accurate to give a range with the following values: best case scenario, some drawbacks (but nothing major), and worst-case.&lt;/p&gt;

&lt;p&gt;Also, all people involved in the estimate should understand the unit of effort you'll be using. For example, if you're using story points, have an example of what a 1 or 3 points feature looks like. If you're using time, explain if you expect this to be "work-hours" or "productive non-interrupted hours."&lt;/p&gt;

&lt;p&gt;For high-level estimates, I've found &lt;a href="https://explainagile.com/blog/t-shirt-size-estimation/"&gt;T-Shirt size estimation&lt;/a&gt; the easiest to use. You can also estimate in weeks or months.&lt;/p&gt;

&lt;p&gt;For low-level estimates, story points are a very wide-spread unit to use because they already take into account uncertainty and risk. You can also use man-hours but be explicit about how you will handle uncertainty and risk; you can add a percentage or a formula based on your past results and other variables. When estimating significant efforts, increase the amount of risk since things like integration, communication, and dependency issues are more likely to happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gather all possible information
&lt;/h3&gt;

&lt;p&gt;This step varies from high-level to low-level estimates. With high-level estimates, you probably won't go much into detail and identify the main components/tasks of the project. For low-level estimates, you'll want to understand things like assumptions, inputs, outputs, UI design, non-functional requirements, dependencies, happy-paths, and edge-cases. Having your own &lt;a href="https://www.scruminc.com/definition-of-ready/"&gt;definition of ready&lt;/a&gt; is useful here.&lt;/p&gt;

&lt;p&gt;Make sure you ask questions and clarify when needed.&lt;/p&gt;

&lt;p&gt;I can't stress this enough &lt;strong&gt;don't rush it&lt;/strong&gt;. Software estimation is an essential step in the software development life cycle, and it has a massive impact on stakeholders' expectations. On the other hand, &lt;strong&gt;don't take forever&lt;/strong&gt;, the lower level you go into an estimate, the higher the cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defer estimation if more information is needed
&lt;/h3&gt;

&lt;p&gt;If you have a big unknown and need to do a bit of research, do it before providing an estimate. If you definitely can't wait, give the estimate but underline that you have some assumptions about that estimate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Give your estimate
&lt;/h3&gt;

&lt;p&gt;Now that you have selected a unit of effort, you have split your workload, and you have researched the necessary information; you only need to start assigning numbers. I have found better results using a consensus-based technique like &lt;a href="https://www.mountaingoatsoftware.com/agile/planning-poker"&gt;planning poker&lt;/a&gt; rather than having a single person like a tech lead estimate on its own. The former allows more people to identify edge-cases, bring their experience, and have more ownership of the final number.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do if you know you are going to miss an estimate 😤
&lt;/h2&gt;

&lt;p&gt;After what I've presented here, it's clear that estimates often fail. So we should be prepared for such cases. First and foremost, if you know your estimate will be missed, have a precise analysis of how behind-schedule you are, the reasons for the delay, accompanied by a proposal of how it can be amended or at least minimized.&lt;/p&gt;

&lt;p&gt;Then, proceed to deliver the bad news so you can adjust your plans and ask for help. Be clear explaining the reasons and avoid compromising the software's quality since that will be more costly in the long-run.&lt;/p&gt;

&lt;p&gt;Finally, do not fall prey to the man-month myth where you think people and effort are interchangeable. Adding new people to a delayed project almost always causes it to slow even further because of communication and training.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this far. I hope this article has provided you with useful information to improve your estimates and reach your organization's or personal goals. Don't forget to share the article with your team! 🗣️&lt;/p&gt;

</description>
      <category>estimation</category>
      <category>softwareengineering</category>
      <category>collaboration</category>
      <category>agile</category>
    </item>
    <item>
      <title>9 concepts you should know from functional programming</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Mon, 06 Jul 2020 18:16:11 +0000</pubDate>
      <link>https://forem.com/victorandcode/9-concepts-you-should-know-from-functional-programming-2en2</link>
      <guid>https://forem.com/victorandcode/9-concepts-you-should-know-from-functional-programming-2en2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://www.victorandcode.com/9-concepts-you-should-know-from-functional-programming?ref=devto"&gt;my personal blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rYr62Eck--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y3bwxtk1mdh0q8dl8jj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rYr62Eck--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y3bwxtk1mdh0q8dl8jj4.png" alt="Functional programming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's begin by defining what functional programming is (FP from now on). FP is a programming paradigm where software is written by applying and composing functions. A &lt;strong&gt;paradigm&lt;/strong&gt; is a "Philosophical or theoretical framework of any kind." In other words, FP is a way for us to think of problems as a matter of interconnecting functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article aims to give a basic understanding of fundamental concepts in FP and some of the problems it helps solve.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: For practicality, I'll omit specific mathematical properties that define these concepts. This is not necessary for you to use these concepts and apply them in your programs.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutability
&lt;/h2&gt;

&lt;p&gt;A mutation is a modification of the value or structure of an object. Immutability means that something cannot be modified. Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;cartProducts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nintendo Switch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;320.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Play station 4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;350.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&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="c1"&gt;// Let's format the price field so it includes the currency e.g. 320 €&lt;/span&gt;
&lt;span class="nx"&gt;cartProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currencySign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&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;€&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;$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Alert! We're mutating the original object&lt;/span&gt;
  &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&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;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&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="nx"&gt;currencyName&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="c1"&gt;// Calculate total&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;cartProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;product&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;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Now let's print the total&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Prints '0320 €350 $' 😟&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What happened? Since we're mutating the &lt;code&gt;cartProducts&lt;/code&gt; object, we &lt;strong&gt;lose the original value&lt;/strong&gt; of price.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutation can be problematic because it makes tracing the state changes in our application hard or even impossible&lt;/strong&gt;. You don't want to call a function in a third party library and not know if it will modify the object you're passing.&lt;/p&gt;

&lt;p&gt;Let's look at a better option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;cartProducts&lt;/span&gt; &lt;span class="o"&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;productsWithCurrencySign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cartProducts&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;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currencyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&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;euros&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;dollars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="c1"&gt;// Copy the original data and then add priceWithCurrency&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;priceWithCurrency&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="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&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="nx"&gt;currencyName&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="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nx"&gt;cartProducts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;product&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;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Prints 670 as expected 😎&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, instead of modifying the original object, we clone the data in the original &lt;code&gt;cartProducts&lt;/code&gt; by using the spread operator&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;priceWithCurrency&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="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&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="nx"&gt;currencyName&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this second option, we avoid mutating the original object by creating a new one that has the &lt;code&gt;priceWithCurrency&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Immutability can actually be mandated by the language. JavaScript has the &lt;code&gt;Object.freeze&lt;/code&gt; utility, but there are also mature libraries such as &lt;code&gt;Immutable.js&lt;/code&gt; you can use instead. Nevertheless, before enforcing immutability everywhere, evaluate the tradeoff of adding a new library + the extra syntax; maybe you'd be better off creating an agreement in your team not to mutate objects if possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function composition
&lt;/h2&gt;

&lt;p&gt;It's the application of a function to the output of another function. Here's a small example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;deductTaxes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grossSalary&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;grossSalary&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addBonus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;grossSalary&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;grossSalary&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;netSalary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;addBonus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deductTaxes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In practice, this means we can split out algorithms into smaller pieces, reuse them throughout our application, and test each part separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deterministic functions
&lt;/h2&gt;

&lt;p&gt;A function is deterministic if, given the same input, it returns the same output. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;joinWithComma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;names&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;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;joinWithComma&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shrek&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Donkey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="c1"&gt;// Prints Shrek, Donkey&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;joinWithComma&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shrek&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Donkey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="c1"&gt;// Prints Shrek, Donkey again!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;A common non-deterministic function is &lt;code&gt;Math.random&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Maybe we get 0.6924493472043922&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Maybe we get 0.4146573369082662&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Deterministic functions help your software's behavior be more predictable and make the chance of bugs lower.&lt;/p&gt;

&lt;p&gt;It's worth noting that we don't always want deterministic functions. For example, when we want to generate a new ID for a database row or get the current date in milliseconds, we need a new value to be returned on every call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pure functions
&lt;/h2&gt;

&lt;p&gt;A pure function is a function that is &lt;strong&gt;deterministic&lt;/strong&gt; and &lt;strong&gt;has no side-effects&lt;/strong&gt;. We already saw what deterministic means. A side-effect is a modification of state outside the local environment of a function.&lt;/p&gt;

&lt;p&gt;Let's look at a function with a nasty side-effect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;sessionState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ACTIVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionIsActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastLogin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expirationDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastLogin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;expirationDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Modify state outside of this function 😟&lt;/span&gt;
    &lt;span class="nx"&gt;sessionState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EXPIRED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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;expirationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;01&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;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&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;isActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionIsActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expirationDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// This condition will always evaluate to false 🐛&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;sessionState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ACTIVE&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="nx"&gt;logout&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;As you can see, &lt;code&gt;sessionIsActive&lt;/code&gt; modifies a variable outside its scope, which causes problems for the function caller.&lt;/p&gt;

&lt;p&gt;Now here's an alternative without side-effects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;sessionState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ACTIVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sessionIsActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastLogin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expirationDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastLogin&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;expirationDate&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="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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;getSessionState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ACTIVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isActive&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EXPIRED&lt;/span&gt;&lt;span class="dl"&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;currentState&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;expirationDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;01&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;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&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;isActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionIsActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentDate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expirationDate&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;newState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getSessionState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Now, this function will only logout when necessary 😎&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;sessionState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ACTIVE&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="nx"&gt;logout&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's important to understand we don't want to eliminate all side-effects since all programs need to do some sort of side-effect such as calling APIs or printing to some stdout. What we want is to minimize side-effects, so our program's behavior is easier to predict and test.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-order functions
&lt;/h2&gt;

&lt;p&gt;Despite the intimidating name, high-order functions are just functions that either: take one or more functions as arguments, or returns a function as its output.&lt;/p&gt;

&lt;p&gt;Here's an example that takes a function as a parameter and also returns a function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;simpleProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;longRunningTask&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="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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Started running at: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;getTime&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="nx"&gt;longRunningTask&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Finished running at: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;getTime&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="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;calculateBigSum&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;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;for&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;counter&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;counter&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;counter&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runCalculationWithProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;simpleProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calculateBigSum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;runCalculationWithProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, we can do cool stuff, such as adding functionality around the execution of the original function. We'll see other uses of higher-order in curried functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arity
&lt;/h2&gt;

&lt;p&gt;Arity is the number of arguments that a function takes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// This function has an arity of 1. Also called unary&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stringify&lt;/span&gt; &lt;span class="o"&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="s2"&gt;`Current number is &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="c1"&gt;// This function has an arity of 2. Also called binary&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;=&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="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;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's why in programming, you sometimes hear &lt;code&gt;unary&lt;/code&gt; operators such as &lt;code&gt;++&lt;/code&gt; or &lt;code&gt;!&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Curried functions
&lt;/h2&gt;

&lt;p&gt;Curried functions are functions that take multiple parameters, only that one at a time (have an arity of one). They can be created in JavaScript via high-order functions.&lt;/p&gt;

&lt;p&gt;Here's a curried function with the ES6 arrow function syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;generateGreeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocassion&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;relationship&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;name&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`My dear &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;relationship&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. Hope you have a great &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ocassion&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;generateGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;birthday&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Specialized greeter for cousin birthday&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greeterCousin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cousin&lt;/span&gt;&lt;span class="dl"&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;cousins&lt;/span&gt; &lt;span class="o"&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;Jamie&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;Tyrion&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;Cersei&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nx"&gt;cousins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;cousin&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;greeterCousin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cousin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="cm"&gt;/* Prints:
  My dear cousin Jamie. Hope you have a great birthday
  My dear cousin Tyrion. Hope you have a great birthday
  My dear cousin Cersei. Hope you have a great birthday
*/&lt;/span&gt;

&lt;span class="c1"&gt;// Specialized greeter for friends birthday&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greeterFriend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;greeter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;friend&lt;/span&gt;&lt;span class="dl"&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;friends&lt;/span&gt; &lt;span class="o"&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;Ned&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;John&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;Rob&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;friends&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;friend&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;greeterFriend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;friend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="cm"&gt;/* Prints:
  My dear friend Ned. Hope you have a great birthday
  My dear friend John. Hope you have a great birthday
  My dear friend Rob. Hope you have a great birthday
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Great right? We were able to customize the functionality of our function by passing one argument at a time.&lt;/p&gt;

&lt;p&gt;More generally, curried functions are great for giving functions polymorphic behavior and to simplify their composition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functors
&lt;/h2&gt;

&lt;p&gt;Don't get intimidated by the name. Functors are just an abstractions that wraps a value into a context and allows mapping over this value. Mapping means applying a function to a value to get another value. Here's how a very simple Functor looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;Identity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="na"&gt;valueOf&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="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

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



&lt;p&gt;Why would you go over the trouble of creating a Functor instead of just applying a function? To facilitate function composition. Functors are agnostic of the type inside of them so you can apply transformation functions sequentially. Let's see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;double&lt;/span&gt; &lt;span class="o"&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="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;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plusTen&lt;/span&gt; &lt;span class="o"&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="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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doubledPlus10&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Identity&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="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&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;plusTen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doubledPlus10&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Prints 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This technique is very powerful because you can decompose your programs into smaller reusable pieces and test each one separately without a problem. In case you were wondering, JavaScript's &lt;code&gt;Array&lt;/code&gt; object is also a Functor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monads
&lt;/h2&gt;

&lt;p&gt;A Monad is a Functor that also provides a &lt;code&gt;flatMap&lt;/code&gt; operation. This structure helps to compose type lifting functions. We'll now explain each part of this definition step by step and why we might want to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are type lifting functions?
&lt;/h3&gt;

&lt;p&gt;Type lifting functions are functions that wrap a value inside some context. Let's look at some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Here we lift x into an Array data structure and also repeat the value twice.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;repeatTwice&lt;/span&gt; &lt;span class="o"&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="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;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Here we lift x into a Set data structure and also square it.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setWithSquared&lt;/span&gt; &lt;span class="o"&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="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&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;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Type lifting functions can be quite common, so it makes sense we would want to compose them.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a flat function
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;flat&lt;/code&gt; function (also called join) is a function that extracts the value from some context. You can easily understand this operation with the help of JavaScript's Array.prototype.flat function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Notice the [2, 3] inside the following array. 2 and 3 are inside the context of an Array&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;favouriteNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// JavaScript's Array.prototype.flat method will go over each of its element, and if the value is itself an array, its values will be extracted and concatenated with the outermost array.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;favouriteNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flat&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Will print [1, 2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  What is a flatMap function
&lt;/h3&gt;

&lt;p&gt;It's a function that first applies a mapping function (map), then removes the context around it (flat). Yeah... I know it's confusing that the operations are not applied in the same order as the method name implies.&lt;/p&gt;

&lt;h3&gt;
  
  
  How are monads useful
&lt;/h3&gt;

&lt;p&gt;Imagine we want to compose two type lifting functions that square and divide by two inside a context. Let's first try to use map and a very simple functor called Identity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;Identity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// flatMap: f =&amp;gt; f(value),&lt;/span&gt;
  &lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&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;value&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="na"&gt;valueOf&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="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// The `of` method is a common type lifting functions to create a Monad object.&lt;/span&gt;
&lt;span class="nx"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;squareIdentity&lt;/span&gt; &lt;span class="o"&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;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&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;**&lt;/span&gt; &lt;span class="mi"&gt;2&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;divideByTwoIdentity&lt;/span&gt; &lt;span class="o"&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;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&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;/&lt;/span&gt; &lt;span class="mi"&gt;2&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="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;squareIdentity&lt;/span&gt;&lt;span class="p"&gt;)&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;divideByTwoIdentity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 💣 This will fail because will receive an Identity.of(9) which cannot be divided by 2&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

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



&lt;p&gt;We cannot just use the map function and need to first extract the values inside of the Identity. Here's where the flatMap function comes into place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;Identity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;valueOf&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="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;squareIdentity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;divideByTwoIdentity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Logs out 4.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are finally able to compose type lifting functions, thanks to monads.&lt;/p&gt;

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

&lt;p&gt;I hope this article gives you a basic understanding of some fundamental concepts in functional programming and encourages you to dig deeper into this paradigm so you can write more reusable, maintainable, and easy-to-test software.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>javascript</category>
      <category>programmingparadigms</category>
      <category>functioncomposition</category>
    </item>
    <item>
      <title>Should you be using Deno instead of Node.js?</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Sun, 24 May 2020 19:27:23 +0000</pubDate>
      <link>https://forem.com/victorandcode/should-i-be-using-deno-instead-of-node-js-4h67</link>
      <guid>https://forem.com/victorandcode/should-i-be-using-deno-instead-of-node-js-4h67</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://www.victorandcode.com/should-i-be-using-deno-instead-of-node-js?ref=devto"&gt;my personal blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A new contender is threatening Node.js monopoly as a JavaScript runtime, and its name is (drumrolls) Deno.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QYVo1po1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kg1gqucf86k5ygo8spwa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QYVo1po1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kg1gqucf86k5ygo8spwa.jpg" alt="Deno"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article will give you a basic understanding of what Deno is, the value this technology adds, and where it lacks at the moment. Also, I'll share some thoughts about adopting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  In a nutshell, what is Deno?
&lt;/h2&gt;

&lt;p&gt;Deno is a new (version 1.0 just came out) JavaScript runtime, created by the Node.js creator and designed to overcome several design flaws from Node.js and add improvements on top of that. A runtime is a "box" where code can run, and it's a vital part of a system because it imposes certain &lt;strong&gt;restrictions&lt;/strong&gt; around applications built inside of it and dictates a tremendous amount of the &lt;strong&gt;development experience&lt;/strong&gt; and &lt;strong&gt;tradeoffs&lt;/strong&gt; involved in creating the system.&lt;/p&gt;

&lt;p&gt;Before checking Deno's benefits, we need to understand which problems it aims to address.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Node.js
&lt;/h2&gt;

&lt;p&gt;On this great &lt;a href="https://www.youtube.com/watch?v=M3BM9TB-8yA"&gt;talk&lt;/a&gt;, Ryan Dahl, the creator of Node.js, talks about some of the regrets in the development of Node.js&lt;/p&gt;

&lt;p&gt;Amongst them, I'd like to highlight the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security: There was a missed opportunity while designing Node to add certain guarantees around security. For example, your linter should not get access to your network or entire file system.&lt;/li&gt;
&lt;li&gt;Making npm the defacto standard: This creates a centralized and privately controlled entity that has great power over the whole ecosystem and things like &lt;a href="https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/"&gt;this&lt;/a&gt; happen.&lt;/li&gt;
&lt;li&gt;node_modules: You know the meme, nothing is deeper than the node modules folder. It complicates the module resolution algorithm and is very inconsistent with how browsers work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After reading this, you might be wondering: "Why not just fix these issues in Node?". Deno's blog answers this question: "Due to the large number of users that Node has, it is difficult and slow to evolve the system."&lt;/p&gt;

&lt;p&gt;Another great benefit of using Deno is the complexity around developing JavaScript applications with Node. There is just massive tooling involved, which creates confusion amongst new developers and headaches to more experienced ones for having to keep up with new versions of each package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of using Deno
&lt;/h2&gt;

&lt;p&gt;Some of Deno's most important benefits compared to Node are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secure by default: Just like mobile applications, you need to grant explicit permission to access file, network, or environment. Because of this, you don't have to be scared anymore about one corrupted package stealing your personal information.&lt;/li&gt;
&lt;li&gt;Simplicity: Deno ships as a single executable, which provides everything you need to develop your application. No need for a package.json file or setting up external config files.&lt;/li&gt;
&lt;li&gt;Support for TypeScript out of the box: Given Typescript popularity and adoption, this can significantly improve the developer experience and help developers catch bugs early.&lt;/li&gt;
&lt;li&gt;Built-in utilities such as a bundler and code formatter: In other words, there is no need for external dependencies such as Prettier or Webpack for common tasks.&lt;/li&gt;
&lt;li&gt;Standard library: This has been a long-requested feature for JavaScript, and Deno offers one. It provides utilities for testing, date-formatting, and more.&lt;/li&gt;
&lt;li&gt;Browser compatible API: Global variables and events such as fetch, load, unload, and window are available in Deno just like you would expect in a browser, thus reducing the friction of moving from one platform to another.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these benefits translate to mainly two things. First, you significantly improve developer experience, thus leading to potentially shorter development cycles, and second, you reduce the risk of downtime and data loss due to vulnerabilities from unsecured scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does a script built for Deno look like
&lt;/h3&gt;

&lt;p&gt;To exemplify Deno's benefits, here's a sample &lt;code&gt;index.ts&lt;/code&gt; file that you can run out of the box with Deno.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Importing a dependency directly from a URL 🤯&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parseDateTime&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std/datetime/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Using browser compatible apis such as fetch&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://icanhazdadjoke.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&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;Accept&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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;enc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Using the Deno global namespace for os utilities&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;joke-of-the-day.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;enc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;We're done here 🦕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;How to run the script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;deno run &lt;span class="nt"&gt;--allow-read&lt;/span&gt; &lt;span class="nt"&gt;--allow-write&lt;/span&gt; index.ts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Deno's limitations
&lt;/h2&gt;

&lt;p&gt;Despite all the significant merits, Deno has some shortcomings that prevent it from being on the same level as Node today. Here they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Migration cost: Most organizations using Node, are tightly coupled to npm's ecosystem. For example, teams have thousands of tests written with Jest, their configuration for prettier, their custom Webpack config, Node global variables, and much more. Adopting Deno for these types of applications would probably be more costly than to keep using Node and npm. Also, if you use Deno for new projects, there would be extra effort maintaining utilities that work for this runtime and a lot of effort would be wasted&lt;/li&gt;
&lt;li&gt;Incompatibility with some NPM packages: One study referenced in this &lt;a href="https://youtu.be/H8IaDYrv-3E?t=2131"&gt;talk&lt;/a&gt; from 2019 suggests that the reason JavaScript is the most popular language today is because of the large number of packages available in the npm registry. Unfortunately, some very popular Node packages are not compatible with Deno.&lt;/li&gt;
&lt;li&gt;The standard module is not stable: According to the docs, "Deno's standard modules (&lt;a href="https://deno.land/std/"&gt;https://deno.land/std/&lt;/a&gt;) are not yet stable": This means that you could end up finding some unexpected behavior with one of your use cases or even bugs.&lt;/li&gt;
&lt;li&gt;Lack of experienced developers using it: This means that even if companies decide to use Deno, finding experts would be challenging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion, should you adopt it now?
&lt;/h2&gt;

&lt;p&gt;In my opinion, if you're talking about using Deno for production apps, then you should NOT (for now). The technology is still in its early stages, which means the ecosystem isn't mature enough to support the thousands of use cases companies have for Node and also the common problems that will arise with Deno that don't have an answer in the JavaScript community. Finally, working with unstable APIs is a dangerous game. You can end up needing to create a pull request to Deno itself to support a critical application.&lt;/p&gt;

&lt;p&gt;On the other hand, if you're talking about side projects, then definitely give it a go. The technology does provide great benefits as it is and should allow you to bootstrap a new project in no time. Also, the community is thriving, so the more you use it, the more you can contribute to its growth.&lt;/p&gt;

&lt;p&gt;Just take in mind all the limitations I mentioned and enjoy building JavaScript apps with no node_modules folder. 🎉&lt;/p&gt;

</description>
      <category>deno</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>node</category>
    </item>
    <item>
      <title>Lessons from migrating a web application to a design system</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Sat, 02 May 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/victorandcode/lessons-from-migrating-a-web-application-to-a-design-system-2701</link>
      <guid>https://forem.com/victorandcode/lessons-from-migrating-a-web-application-to-a-design-system-2701</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sDDC2NVT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ey49c4ft7b3kgpmnot1h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sDDC2NVT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ey49c4ft7b3kgpmnot1h.jpg" alt="Birds migrating"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also available in my &lt;a href="https://www.victorandcode.com/migrating-to-a-design-sytem-lessons-learned?ref=devto"&gt;personal blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a design system
&lt;/h2&gt;

&lt;p&gt;In the world of frontend development, a design system is a set of common guidelines, UI components, and reusable utilities that allow for the rapid creation of applications.&lt;/p&gt;

&lt;p&gt;Some notable examples are: &lt;a href="https://primer.style/design/"&gt;Github's Primer&lt;/a&gt; or &lt;a href="https://design.firefox.com/photon/"&gt;Mozilla's Photon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They provide the following benefits (amongst others):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster time to market&lt;/li&gt;
&lt;li&gt;Consistency between products&lt;/li&gt;
&lt;li&gt;Less code to maintain&lt;/li&gt;
&lt;li&gt;Robustness&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The story of this initiative
&lt;/h2&gt;

&lt;p&gt;I recently had the opportunity to champion an initiative to migrate an application of ~15k lines of code, and approximately 239 React components. This meant being responsible for splitting the effort to implement the initiative, provide appropriate details and context to the rest of the team, lead refinement sessions around these tasks, and following up their progress.&lt;/p&gt;

&lt;p&gt;The objective of this initiative was to replace existing React components written in pure &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; and &lt;a href="https://styled-components.com/"&gt;styled-components&lt;/a&gt; with the design system's alternative for these components. This also included migrating utilities for responsive design, spacing, and font. Finally, files that were no longer needed would be removed from the original codebase.&lt;/p&gt;

&lt;p&gt;Next, I'll describe how the effort was planned and executed, as well as share some lessons learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The goals
&lt;/h2&gt;

&lt;p&gt;There were three goals that we wanted to achieve by implementing this initiative:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reduce codebase while keeping functionality: Generally speaking, if you have less code in your application, it's easier to maintain and it's less prone to error.&lt;/li&gt;
&lt;li&gt;Reduce development time for new frontend tasks: After the migration, we'd be dealing mostly with the components from the design system which means it would be easier to change their behavior through one of the configuration properties it provides.&lt;/li&gt;
&lt;li&gt;Reduce wasted effort for future initiatives: Given that we would delete custom components, utilities, test files, and assets, all of these files wouldn't add effort to future technical debt initiatives.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  State of the website previous to migration
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Test coverage&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;87.09% statements, 79.65% functions, 87.64% lines&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript files&lt;/td&gt;
&lt;td&gt;441&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines of code without blank lines and comments&lt;/td&gt;
&lt;td&gt;14908&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI components &lt;strong&gt;these are the ones we'd be replacing&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;215&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container components (components with complex logic in them)&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The high test coverage gave us confidence that we could do this migration without having to worry to much about breaking stuff. Of course, each developer still did testing around each task.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plan
&lt;/h2&gt;

&lt;p&gt;During kickoff, the following plan was shared with the frontend team to address the migration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Split workload amongst 16 tasks of similar-effort&lt;/li&gt;
&lt;li&gt;Timespan: 3.5 sprints (the initiative was developed alongside regular sprint objectives)&lt;/li&gt;
&lt;li&gt;Implement between 3 to 5 tasks per sprint&lt;/li&gt;
&lt;li&gt;Bi-weekly refinements to scope the tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;

&lt;p&gt;In this section, I'll give some comments analyzing the impact that this initiative had on the project. First, the numbers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Components that were deleted&lt;/td&gt;
&lt;td&gt;35.81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other files deleted (% of overall codebase files)&lt;/td&gt;
&lt;td&gt;6.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Net number of lines deleted&lt;/td&gt;
&lt;td&gt;12.36%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Components that were deleted
&lt;/h3&gt;

&lt;p&gt;Of the 215 UI components, 77 were deleted which accounts for a 35.81% reduction. This accomplishes objectives 1 and 3 of the initiative given that there is a significant proportion of UI components that don't need to be maintained anymore. You might wonder why there is still 64% of UI components remaining in the application. The answer is mostly application-specific components. This might also indicate that some reusable components should be included in a future version of our design library.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other files deleted
&lt;/h3&gt;

&lt;p&gt;As expected, some utility files were deleted, albeit not a huge amount. Still, given that we don't have these in the code anymore, a new developer will not get confused and use them by accident.&lt;/p&gt;

&lt;h3&gt;
  
  
  Net number of lines deleted
&lt;/h3&gt;

&lt;p&gt;The impact in the overall size of the project is smaller (12.36%) than the impact of % of components deleted. Nevertheless, this shoudn't be discouraging because after the migration the UI has the added robustness from the design system which also makes it less prone to error.&lt;/p&gt;

&lt;p&gt;We should also remember that, even though the UI components are a critical part of a frontend application, there are several other concerns such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Container components&lt;/li&gt;
&lt;li&gt;Test files&lt;/li&gt;
&lt;li&gt;State Management&lt;/li&gt;
&lt;li&gt;Custom hooks&lt;/li&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Constants&lt;/li&gt;
&lt;li&gt;API calls&lt;/li&gt;
&lt;li&gt;Configuration&lt;/li&gt;
&lt;li&gt;3rd party wrappers (i18n, date formatting, tracking)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;p&gt;These are some other lessons I gathered from the whole process of implementing this initiative that made it possible for it to be completed on time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Due to the fact that we used react-testing-library and followed its &lt;a href="https://testing-library.com/docs/guiding-principles"&gt;guiding principles&lt;/a&gt;, we weren't concerned with breaking our tests because the underlying implementation changed. This made the transition much smoother.&lt;/li&gt;
&lt;li&gt;Keep reusable code for the end of the migration, so that individual packages can get migrated without being blocked.&lt;/li&gt;
&lt;li&gt;When migrating to a new component library, make sure to validate with designers to make sure expectations of UI are met.&lt;/li&gt;
&lt;li&gt;Communicate with your product owner so they are aware of the changes being made from the UI perspective.&lt;/li&gt;
&lt;li&gt;Communicate continuously with teams before a sprint start so technical tickets can be assigned according to capacity and adjustments to the plan can be made.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;If you have a mature enough design system, the impact of adopting it in a web application can be hugely positive for reducing the amount of code in your UI layer. It can also help detect gaps in the design system's functionality that can later help to improve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credit
&lt;/h2&gt;

&lt;p&gt;The migration was possible thanks to my amazing colleagues at the @FREENOW frontend chapter in the Barcelona Tech hub and the design system team.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>refactoring</category>
      <category>designsystems</category>
    </item>
    <item>
      <title>What to do when you're stuck with a problem 🤷</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Sat, 21 Mar 2020 13:19:13 +0000</pubDate>
      <link>https://forem.com/victorandcode/what-to-do-when-you-re-stuck-with-a-problem-4bjb</link>
      <guid>https://forem.com/victorandcode/what-to-do-when-you-re-stuck-with-a-problem-4bjb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_MO1J69U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l7nh1ui601unc2tkdie1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_MO1J69U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l7nh1ui601unc2tkdie1.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I mean by "stuck"
&lt;/h2&gt;

&lt;p&gt;Here's how I frame this kind of situation. Being stuck means that you're not able to finish or make progress in a task with your current &lt;strong&gt;knowledge&lt;/strong&gt;, &lt;strong&gt;mental state&lt;/strong&gt; or &lt;strong&gt;physical state&lt;/strong&gt;. It happens every once in a while and requires special consideration to tackle it effectively. Some examples are: not being able to solve a bug or not being able to find a good design that satisfies all the constraints of a given problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to tell that you're stuck
&lt;/h2&gt;

&lt;p&gt;The first step towards getting unstuck is to recognize you're stuck. Here are some ways to determine this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you're not making any progress for a little while. For me, this usually means half an hour to an hour&lt;/li&gt;
&lt;li&gt;When you're feeling deeply frustrated with a problem&lt;/li&gt;
&lt;li&gt;When you're unable to understand the problem and its factors. For example, when you need to implement a feature in a platform or with a library you're not familiar with&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to do when you're stuck
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The mindset
&lt;/h3&gt;

&lt;p&gt;Usually, we grow the most when we're faced with challenges, so &lt;strong&gt;every time you get stuck, recognize that you found an opportunity to grow&lt;/strong&gt;. It might be hard to get through it but it will be rewarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  The physical aspect of it
&lt;/h3&gt;

&lt;p&gt;Our minds need to be in a good physical state to solve problems. Some of the things that can make put it in a bad state are &lt;a href="https://www.youtube.com/watch?v=WuyPuH9ojCE"&gt;stress&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=gedoSfZvBgE"&gt;lack of sleep&lt;/a&gt; or an &lt;a href="https://www.webmd.com/diet/ss/slideshow-diet-for-stress-management"&gt;unhealthy diet&lt;/a&gt;. It's critical for you to get into a positive mental state. Here are some techniques you can use to achieve that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get away from the computer (if your problem presents there). This will help your mind rest from being exposed to the problem and achieve some relaxation, as well as allowing you to think of the big picture of where this problem fits. Even better, take a walk if you can.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=hFcQpNr_KA4"&gt;Breathe mindfully&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Eat the right type of food&lt;/li&gt;
&lt;li&gt;Try to get the right amount of sleep&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to go deeper into this topic, I really recommend watching &lt;a href="https://www.youtube.com/watch?v=0xc3XdOiGGI&amp;amp;list=PLdKSPx5SPdB7F0Fyb3e5dv29F4QfqLsh4&amp;amp;index=3&amp;amp;t=0s"&gt;this&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Do your homework
&lt;/h3&gt;

&lt;p&gt;Always do some research on the problem. Try to identify what are its key elements: a specific layer of your application, given technology, a specific set of conditions or constraints. Then, &lt;strong&gt;google it&lt;/strong&gt;. It's very likely someone already solved that problem (or a very similar one).&lt;/p&gt;

&lt;p&gt;If you have just a thin idea of where a possible solution might be, spend some time learning everything you can around the related technologies/topics. Search for articles, documentation on the API/technology, common patterns, etc. In case you're wondering, yes, learning is part of your job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ask for help
&lt;/h3&gt;

&lt;p&gt;If you're unable to find a solution on your own or need to solve the problem very urgently. You can ask somebody who is familiar with the problem such as a friend or colleague. Also, you can go into an online community such as StackOverflow and ask there for help.&lt;/p&gt;

&lt;h3&gt;
  
  
  If everything else fails
&lt;/h3&gt;

&lt;p&gt;Apply the diffuse mode. This is an underused way of using your brain to solve problems in the background. Learn about it &lt;a href="https://www.youtube.com/watch?v=1FvYJhpNvHY"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A note for people starting out in the world of programming
&lt;/h2&gt;

&lt;p&gt;It's normal that at the start of your career you find these kinds of situations more often. It's normal. Even if you're very experienced, you'll still find these situations but you'll have better tools to tackle them faster and efficiently.&lt;/p&gt;

&lt;p&gt;Feel free to share your experiences of getting stuck and how you overcame it.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>bugs</category>
      <category>beginners</category>
    </item>
    <item>
      <title>👨‍💻📚 65 practical lessons from "The Pragmatic Programmer: From Journeyman to Master"</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Wed, 12 Feb 2020 21:29:03 +0000</pubDate>
      <link>https://forem.com/victorandcode/65-practical-lessons-from-the-pragmatic-programmer-from-journeyman-to-master-136a</link>
      <guid>https://forem.com/victorandcode/65-practical-lessons-from-the-pragmatic-programmer-from-journeyman-to-master-136a</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QEn1I6Zi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nmm4vjpn3q7bw4obgl65.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QEn1I6Zi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nmm4vjpn3q7bw4obgl65.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"The Pragmatic Programmer: From Journeyman to Master" is a book that has had a profound impact on my career as a developer. I've found myself often coming back to it to check my notes and highlights, so to make this more practical, I created this compilation. Please take this article as a teaser for the entire book. I highly encourage you to read it yourself.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer&lt;/em&gt;: These bullet points are me paraphrasing sentences from the book, others are direct quotes (these are between double-quotes). Also, these notes are for the first edition of the book, I haven't yet checked out the second edition but from the table of contents, it seems like the authors added more stuff into it rather than removing from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  List of lessons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To be a pragmatic programmer, be: "Early adopter/fast adapter", "Inquisitive", "Critical thinker", "Realistic", "Jack of all trades". In short "Care about your craft". Page xviii&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What distinguishes a pragmatic programmer? The attitude to thinking beyond the immediate problem and take the context into account. Also, they are accountable for everything they do. Page 1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does a pragmatic programmer take responsibility? Providing options and not making excuses. Page 3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Software can rot, the most important factor that affects this is the people's psychology around a project. Page 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't leave tech debt unfixed. Fix stuff as soon as they pop-up or at least plan to address it later. Page 5&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To make positive change, be proactive so you become a Catalyst for Change. Page 8&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Constantly review what's happening around you, not just what you are doing". Page 9&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you involve users in the trade-offs to identify the real constraints of the project and prioritize accordingly. Page 10&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code can never be perfect. "Great software today is often preferable to perfect software tomorrow". Page 11&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Knowledge and expertise are your most important professional assets". "Unfortunately, they're expiring assets". Page 12&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Think critically about what you read and hear. You need to ensure that the knowledge in your portfolio is accurate". Page 16&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be an effective communicator and think about your audience before delivering the message and be timely when delivering the message. Page 19&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid duplication by having a clear design in mind when tackling a problem. Also, constantly communicate with your peers is key. Page 32&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When evaluating using third party libraries, evaluate if they impose any unwanted restrictions on you. Page 39&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you want to cheaply evaluate a risky decision, prototypes are a great tool. Page 53&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prototypes aren't only to explore features, they can serve to explore architectures, third-party components or UI changes. Page 54&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get familiar with the domain language and use it in your programs. Page 58&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When doing estimations, ask yourself about the context in which this estimate will be used. Do you need a high-level estimate for roadmap planning? Do you need a more precise number for your current sprint?. Page 64&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A good way to estimate something is to ask someone who has done it before. Page 65&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Often the only way to truly determine the timetable for a project is by gaining experience on that project. Page 68&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When asked for an estimate, answering "I'll get back to you" will help you slow down the process, apply several decomposition techniques (more detail in the book) and provide a better answer. Page 69&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consider using plain text as a format to represent knowledge given its simplicity, longevity, and ease of use. Page 74&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When debugging, get into the right mindset first. Turn off your ego, any pressure you have from the project you're currently working on and get comfortable. Also, don't panic. Try to discover the root cause instead of just fixing the symptoms. Page 91&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While eliminating possible causes of a bug, recognize that if you change something and the system stopped working, that something is probably the reason why. Page 96&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't assume some function is not related to a bug, prove it, run it with the data that's causing the problem. Page 97&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the bug took a long time to fix, ask yourself what you can do to fix it next time easier. Page 98&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"You can't write perfect software". Page 107&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When your program detects that it entered a state that shouldn't have happened, crash. It's much better to crash than continue running with a corrupted state. Page 121&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Exceptions should rarely be part of a program's normal flow; they should be reserved for unexpected events". Page 126&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A routine that allocates resources should ideally also free them. Page 131&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When asking an object for a particular service, we'd like the service to be performed on our behalf. Do not rely on third-party objects to be returned. Otherwise, you're increasing the coupling of your code to another module. Page 139&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Given the frequency at which business needs can change, it's best to add support for dynamic behavior through configuration at runtime. Page 144&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coding isn't mechanical, there are decisions made every minute. Page 171&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't rely on your programs working by coincidence, be aware of what you're doing and do your coding with a plan in mind. Page 175&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Don't let existing code dictate future code". Page 176&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be pragmatic when choosing your algorithm. The fastest one isn't always the best one. Page 182&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code needs to evolve. Software is more like gardening than to construction. Page 184&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor early and refactor often. Also, keep track of the things that need to be refactored. Page 186&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Don't try to refactor and add functionality at the same time". Page 186&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Before refactoring, make sure you have good tests. Also, do your refactoring in short small steps. Page 186&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built testability into your software from the beginning and test each piece thoroughly before integrating them. Page 189&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you use a tool to generate code for you, understand everything it produces so you can control your application. Page 199&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Software requirements are generally hard to identify. They're usually buried beneath layers of assumptions, misconceptions, and politics. Page 202&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"It's important to discover the underlying reason why users do a particular thing, rather than just the way they currently do it". Page 203&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A simple technique for getting inside your user's requirements is to become a user. Spend some time with them in their actual working environment. Page 203&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Requirements are not architecture, they are not design or user interface. They are needs.". Page 208&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To ensure consistent communication with other stakeholders, maintain a project glossary. Page 210&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When solving though problems, first identify the constraints placed on you and the degree of freedom you have. Challenge any preconceived notions and evaluate whether or not they are hard/absolute constraints or just preconceived notions. Page 213&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When faced with a tough problem, enumerate all the possible solutions you can think of. If you want to dismiss an option, think clearly about the reasons why. Page 213&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When faced with a problem that seems harder than it should be, ask yourself these questions: "Is there an easier way?", "Are you trying to solve the right problem, or have you been distracted by a peripheral technicality?", "Why is this thing a problem?", "What is it that's making it so hard to solve?", "Does it have to be done this way?", "Does it have to be done at all?" Page 214&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't obsess over creating software specifications. Often, it's only during coding that certain options become apparent. Page 218&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"As soon as you have more than one person working on a project, you need to establish some rules and delegate parts of the project accordingly." Page 223&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quality is a team effort, not a single developer effort. Page 224&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your team is a single entity that needs to communicate clearly with the rest of the world. Create a personality for it and generate a positive reputation. Page 225&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Organize your team around functionality, not job function. Page 227&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automate every task everything you can, avoid manual procedures at all cost. Page 231&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pragmatic programmers test their code early, often and automatically. Page 237&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Failing to meet usability criteria is just as a bug as dividing by zero. Page 241&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The data you use for testing has a huge impact on giving you confidence. Don't blindly trust code coverage. Page 245&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a bug slips through the net of existing tests, you need to add a new test to trap it next time. Page 246&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"In general, comments should discuss why something is done, its purpose and goal". Also, it's a good way to document why decisions were made and what other alternatives were discarded. Page 249&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"The success of a project is measured by how well it meets the expectations of your users.". Page 255&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Work with your users so that their understanding of what you'll be delivering is accurate.". Page 256&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go the extra mile to surprise your users, try to delight them. Page 256&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading this far 🙏&lt;/p&gt;

</description>
      <category>books</category>
      <category>pragmaticprogrammer</category>
      <category>selfreflection</category>
    </item>
    <item>
      <title>5 invaluable learning methods for programmers 👩‍💻</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Sun, 29 Dec 2019 18:23:51 +0000</pubDate>
      <link>https://forem.com/victorandcode/5-invaluable-learning-methods-for-programmers-44a8</link>
      <guid>https://forem.com/victorandcode/5-invaluable-learning-methods-for-programmers-44a8</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lRshHQro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3yfts0y7p0ku16lhr14p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lRshHQro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3yfts0y7p0ku16lhr14p.jpg" alt="Cover Puzzle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learning feels sometimes like putting together pieces of a puzzle. Photo by Hans-Peter Gauster on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As developers, learning is an everyday thing. However, there are so many ways to learn that it can easily feel overwhelming. It's helpful to keep in mind that each method has its pros and cons so you can have more effective learning sessions.&lt;/p&gt;

&lt;p&gt;Here are the main methods I use for learning. For each one, I'll answer the following questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What value does it give?&lt;/li&gt;
&lt;li&gt;When to use it?&lt;/li&gt;
&lt;li&gt;What limitations does it have?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: This is by no means an extensive list of all methods available, but these are the main ones I personally use. Feel free to reach out to me with others I'm missing :)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Short online courses (e.g. pluralsight, egghead)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ou_9kSuF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/mo7d6lmc532dcyhgbsrv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ou_9kSuF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/mo7d6lmc532dcyhgbsrv.jpg" alt="Video camera"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by Thomas William on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What value does it give?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to consume: people can follow along when you show them running code instead of just pasting chunks of code&lt;/li&gt;
&lt;li&gt;Fast to consume: when videos are short and centered on a specific sub-topic, you can just watch it and get an idea of the concept it explains&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;First contact with new technology: You can watch a video almost effortlessly and get a sense of what a technology does&lt;/li&gt;
&lt;li&gt;Deepen knowledge in a specific technology: You can find videos from very high-level engineers or even the creators of a technology&lt;/li&gt;
&lt;li&gt;Get common best practices: Common patterns tend to be spread really quickly so someone will usually make a course on it&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What problems does it have?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Subscriptions can get pricey: Good material costs money. It can be a very good investment though&lt;/li&gt;
&lt;li&gt;The theoretical base is many times weak: Since the videos usually focus on practical applications of the technology. The whys behind the design of the example project or the technologies are left as an afterthought&lt;/li&gt;
&lt;li&gt;Examples are sometimes basic: Since time is limited, usually courses take a contrived example and don't give you a broad perspective on a real-world application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Personal projects
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1_Va4K1G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2uni52wtrcc1j40pk8pr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1_Va4K1G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2uni52wtrcc1j40pk8pr.jpg" alt="Light bulb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by Raul Varzar on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm talking about projects you do in your spare time to solve your problems with programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  What value does it give?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Gives you experience making technical decisions: when you solve actual problems instead of hello-worlds, you need to make technical trade-offs, evaluate new technologies and many other real-life decisions. This is a very important muscle to exercise&lt;/li&gt;
&lt;li&gt;Gives you experience with the many aspects of releasing a software project: from frontend to CI to deployment, each one has its intricacies&lt;/li&gt;
&lt;li&gt;Longer lasting learning: we learn better from our mistakes, nothing like a 2-hour configuration bug to make you remember to read the docs ;)&lt;/li&gt;
&lt;li&gt;Provide a playground to try new ideas or technologies: by trying out new approaches you can expand your repertoire and try out new cool tech&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When you have a problem you can solve with technology: you have the skillset, why not use it? Maybe other people have the same problem&lt;/li&gt;
&lt;li&gt;Experimenting with new ideas or technologies&lt;/li&gt;
&lt;li&gt;All the time: there is so much new stuff to try out and updates to existing stuff that it helps to have a working product that needs to be maintained&lt;/li&gt;
&lt;li&gt;When you want to get familiar with a family of technologies: maybe you want to see how it feels to use react with GraphQL? Or how using redux and its many middlewares make you structure your app?&lt;/li&gt;
&lt;li&gt;Profit: hey you never know if you have the next dropbox&lt;/li&gt;
&lt;li&gt;When you want to develop your portfolio&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What problems does it have?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Takes long time and motivation: you have to be disciplined to finish a complete project, even a small one&lt;/li&gt;
&lt;li&gt;Needs clear objective: Either solve a problem or learn. If it doesn't, it can fade into the realm of unfinished ideas&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open source contributions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uZUoELdO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/gtza4j6qhsfz38j8dv3q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uZUoELdO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/gtza4j6qhsfz38j8dv3q.jpg" alt="Forks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by Ursula Spaulding on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What value does it give?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Learn to navigate other people's source code: this is a fundamental skill as a software developer. We spend a large chunk of our time reading other people's code. Big open-source projects will challenge you in that they can be humongous in terms of size. You will need to ask for questions and process other people's way of solving problems&lt;/li&gt;
&lt;li&gt;Discuss technical decisions with very smart people: open source projects need to make sure their decisions don't impact negatively their existing users so prepare to be challenged on a solution you are proposing and defend your arguments&lt;/li&gt;
&lt;li&gt;Learn current best practices and tools: maintained open-source projects need to keep up to date. This means they usually use state-of-the-art technologies to solve their problems&lt;/li&gt;
&lt;li&gt;Learn more about a technology you are using: if you get familiar with how a library you are using works on the inside, it will give you more insight on how to use it better and maybe propose a feature or fix a bug&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;As much as you have time to (at least once every 1-2 months): it will help you challenge yourself with problems you are not familiar with and collaborate with other very smart engineers&lt;/li&gt;
&lt;li&gt;When you want to learn how some technology works on the inside&lt;/li&gt;
&lt;li&gt;Getting up to date on current technologies&lt;/li&gt;
&lt;li&gt;Developing your portfolio of contributions: it is very valued in the industry&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What problems does it have?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Solving the actual ticket can take a long time depending on its complexity and the back and forths with the maintainers&lt;/li&gt;
&lt;li&gt;You have to dig into the issue list to find a worthwhile issue to solve&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Books (technology agnostic and technology-specific)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FVMR_nXX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/syzimslca9ucyazomtg3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FVMR_nXX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/syzimslca9ucyazomtg3.jpg" alt="Books"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by Alfons Morales on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What value does it give?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Quality content: if chosen correctly (by editorial, author or otherwise), you make sure the quality of the book is top-notch&lt;/li&gt;
&lt;li&gt;Deep understanding of specific topics: broadening your toolset with a specific technology will help you choose a more fitting solution&lt;/li&gt;
&lt;li&gt;Convenience for consumption: if physical, you can read them anywhere you like&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All the time: be always reading a technical book, there is so much to learn and it can help you get off the screen for a little while&lt;/li&gt;
&lt;li&gt;Wanting to deepen knowledge into a specific technology&lt;/li&gt;
&lt;li&gt;Wanting to improve your overall thinking process with better mental models and techniques&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What problems does it have?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Long-time to consume: in my experience, to really grasp new ideas from a technical book, you need to re-read and think about the content for a while&lt;/li&gt;
&lt;li&gt;Expensive: technical books are very expensive compared to other non-fiction books&lt;/li&gt;
&lt;li&gt;If technology-specific will probably get out of date quickly&lt;/li&gt;
&lt;li&gt;Need to balance your reading time between technology-agnostic vs technology-specific books, both are important&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Blog posts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7OztVvCe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2q7wuepyy0ud3az3y2kx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7OztVvCe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2q7wuepyy0ud3az3y2kx.jpg" alt="Full inbox"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by Samuel Zeller on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What value does it give?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Solutions to specific problems&lt;/li&gt;
&lt;li&gt;Short learning sessions&lt;/li&gt;
&lt;li&gt;Learn about other people's mistake&lt;/li&gt;
&lt;li&gt;Hands-on solutions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to use it?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All the time, maybe every day depending on your learning schedule&lt;/li&gt;
&lt;li&gt;Solving very specific problems&lt;/li&gt;
&lt;li&gt;Getting started with technology&lt;/li&gt;
&lt;li&gt;Wanting to get deeper into technology or concept&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What problems does it have?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;There is an avalanche of articles every week: hackernews, medium, subscriptions, dev.to, it goes on and on. You need to prioritize which ones to read and keep looking for new sources.&lt;/li&gt;
&lt;li&gt;A lot of noise is generated from duplicated articles: some examples, "Getting started with react.js" or "How to become a programmer".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Communities (e.g. spectrum, slack channels, gitter)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SRO29Wth--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1oi8msmfp0z3ljdcbeb1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRO29Wth--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1oi8msmfp0z3ljdcbeb1.jpg" alt="Threads"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Photo by Héctor J. Rivas on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What value does it give?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Evaluate your ideas&lt;/li&gt;
&lt;li&gt;Learn about other people's thinking process&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to participate in one?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All the time&lt;/li&gt;
&lt;li&gt;Solving a specific problem&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;li&gt;Finding a job&lt;/li&gt;
&lt;li&gt;See what's coming in the future&lt;/li&gt;
&lt;li&gt;While developing a personal project&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What problems does it have?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Needs constant engagement&lt;/li&gt;
&lt;li&gt;You need to dig to find a conversation you are interested in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How do you learn and keep improving your technical skills?&lt;/p&gt;

</description>
      <category>learning</category>
      <category>onlinecourses</category>
      <category>opensource</category>
      <category>blogging</category>
    </item>
    <item>
      <title>Even Swaps, a rational way to choose a library</title>
      <dc:creator>Victor Cordova</dc:creator>
      <pubDate>Tue, 10 Dec 2019 20:30:06 +0000</pubDate>
      <link>https://forem.com/victorandcode/even-swaps-a-rational-way-to-choose-a-library-4839</link>
      <guid>https://forem.com/victorandcode/even-swaps-a-rational-way-to-choose-a-library-4839</guid>
      <description>&lt;p&gt;As developers, we are fortunate enough to have at our disposal a never-ending selection of high-quality libraries to choose from when we want to solve our problems. This creates a new challenge: which one to use and why?&lt;/p&gt;

&lt;p&gt;The main question this article helps answer is how to methodically choose a library that will best fit your needs and will save you time on unwanted refactorings. &lt;strong&gt;This method is most useful when a clear alternative is not clear, and there are several options to choose from&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who are our users? 👨‍💻🙋‍♀️
&lt;/h2&gt;

&lt;p&gt;There are two users we should keep in mind when choosing a library. Each one has his own needs and expectations. &lt;/p&gt;

&lt;p&gt;The first type of user is, of course, the final user of our application. This person expects an easy to use, performant, and beautiful product. She doesn't want to spend time learning how to use your UI or have to read somewhere else what are the steps they need to do their job or solve their problem.&lt;/p&gt;

&lt;p&gt;The second type of user is the developer, who will be using the library. This person expects an easy to use API, plenty of customization available, smart defaults, proper documentation for the library, and that the project is still maintained.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the exact needs your product has?
&lt;/h2&gt;

&lt;p&gt;This is the first question you should be asking. What features are they expecting your library to have? What are the use cases for it? How does the design look like?&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you need a library? 🤔
&lt;/h2&gt;

&lt;p&gt;After understanding the need, you should ask if you need to use an existing library. If the use case is very simple, you might be better off just creating the code yourself or making use of a feature from JavaScript (don't forget to check things in stage 3 of the standard). Just keep in mind the pros and cons of using a library:&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Battle-tested&lt;/li&gt;
&lt;li&gt;It's usually highly customizable&lt;/li&gt;
&lt;li&gt;Best practices baked-in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has a learning curve&lt;/li&gt;
&lt;li&gt;Might require making decisions you might not like (depend on another external library like moment.js, using CSS classes instead of styled-components)&lt;/li&gt;
&lt;li&gt;You'll have to keep it up to date for security reasons&lt;/li&gt;
&lt;li&gt;Adds to your bundle size&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The method to choose a library (Even Swaps)🔄
&lt;/h2&gt;

&lt;p&gt;Alright, let's say you have decided that you are going to need a library, now it's time to apply the method for evaluating the best choice. This is based on a Harvard Business Review publication called "Even Swaps" from authors John S. Hammond, Ralph L. Keeney, and Howard Raiffa published in 1998.&lt;br&gt;
For this example, let's say you have decided you need to choose a datepicker library that will be used in several screens of your app. We'll be creating a matrix of library vs. dimension to evaluate our decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Choosing dimensions
&lt;/h2&gt;

&lt;p&gt;Here's where knowing your two types of user counts, what does each one need? First, let's see what a final user would expect from such a library. We'll assign numbers to qualitative dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good UX (easy to use) (1-5, 5 is best)&lt;/li&gt;
&lt;li&gt;Mobile friendly *&lt;/li&gt;
&lt;li&gt;Supports localization *&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How about the developers? Here are a couple of ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proper documentation (1-5, 5 is best)&lt;/li&gt;
&lt;li&gt;Bundle size (smaller is better)&lt;/li&gt;
&lt;li&gt;Dependencies (no dependencies is ideal)&lt;/li&gt;
&lt;li&gt;Easy to style (1-5, 5 is best)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of the other dimensions is a must, then you can mark it with a * for part 4 of this method. For this particular case, I've marked mobile friendly and localization as musts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Finding relevant options
&lt;/h2&gt;

&lt;p&gt;List out all the options you find after a quick google search. Make sure you also search for alternatives to the first result. You can do this by typing "FIRST ALTERNATIVE vs." and google will autocomplete other options. Finally, you can also tweet or post questions in communities such as Reddit or Spectrum. &lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: Creating a consequence table
&lt;/h2&gt;

&lt;p&gt;For this part, you'll have to read the docs and preferably play around with the library.&lt;/p&gt;

&lt;p&gt;Afterward, you can create a table with the libraries in one axis and the dimensions from step 1 in another axis. This is called a consequence table in the original method. For measuring bundle size, I recommend using bundlephobia.com&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;UX&lt;/th&gt;
&lt;th&gt;Mobile Friendly *&lt;/th&gt;
&lt;th&gt;Supports localization *&lt;/th&gt;
&lt;th&gt;Good documentation&lt;/th&gt;
&lt;th&gt;Bundle size&lt;/th&gt;
&lt;th&gt;Dependencies&lt;/th&gt;
&lt;th&gt;Easy to style&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/airbnb/react-dates/"&gt;react-dates&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (using moment.js)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;231kB&lt;/td&gt;
&lt;td&gt;moment.js&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://reactdatepicker.com/"&gt;react-datepicker&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (internally uses date-fns)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;63.5kB&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;&lt;a href="https://react-day-picker.js.org/"&gt;react-day-picker&lt;/a&gt;&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;No&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Yes (either manual or moment.js))&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;3.7kB&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;None&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, &lt;em&gt;react-date-picker&lt;/em&gt; has been discarded because it's not mobile-friendly, which was one of our must dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 4: Doing even swaps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This is the core of the method&lt;/strong&gt;. It will allow us to narrow down our options to a single one. I'll let the original authors explain it much better than I can:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What do we mean by even swaps? To explain the concept, we need to state an obvious but fundamental principle of decision-making: If every alternative for a given objective is rated equally—for example, if they all cost the same—you can ignore that objective in making your decision. If all airlines charge the same fare for the New York to San Francisco flight, then cost doesn’t matter. Your choice will hinge on only the remaining objectives.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, we want to make two options have the same values for all their dimensions except one; then, we'll use that last dimension to pick the dominating option and discard the other one, as simple as that.&lt;/p&gt;

&lt;p&gt;How do we do this 🤷? We must &lt;strong&gt;determine what it would take to make two options have the same value in one dimension&lt;/strong&gt;. For example, let's say we want to ignore the UX dimension; this would mean we want two options to have the same values. We then ask, how many additional kB of bundle size would I add to give an option two extra points of UX? Let's say it's 150 kB. Let's add 2 UX points to &lt;em&gt;react-datepicker&lt;/em&gt; and increase its bundle size by 150 kB.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;UX&lt;/th&gt;
&lt;th&gt;Mobile Friendly *&lt;/th&gt;
&lt;th&gt;Supports localization *&lt;/th&gt;
&lt;th&gt;Good documentation&lt;/th&gt;
&lt;th&gt;Bundle size&lt;/th&gt;
&lt;th&gt;Dependencies&lt;/th&gt;
&lt;th&gt;Easy to style&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/airbnb/react-dates/"&gt;react-dates&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (using moment.js)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;231kB&lt;/td&gt;
&lt;td&gt;moment.js&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://reactdatepicker.com/"&gt;react-datepicker&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (internally uses date-fns)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;213.5kB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;&lt;a href="https://react-day-picker.js.org/"&gt;react-day-picker&lt;/a&gt;&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;No&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Yes (either manual or moment.js))&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;3.7kB&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;None&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now, the first and second option are almost the same. Let's ask, for two additional points of documentation, how many kB would we add? Let's say it's 80 kB&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;UX&lt;/th&gt;
&lt;th&gt;Mobile Friendly *&lt;/th&gt;
&lt;th&gt;Supports localization *&lt;/th&gt;
&lt;th&gt;Good documentation&lt;/th&gt;
&lt;th&gt;Bundle size&lt;/th&gt;
&lt;th&gt;Dependencies&lt;/th&gt;
&lt;th&gt;Easy to style&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/airbnb/react-dates/"&gt;react-dates&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (using moment.js)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;231kB&lt;/td&gt;
&lt;td&gt;moment.js&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://reactdatepicker.com/"&gt;react-datepicker&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (internally uses date-fns)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;293.5kB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;&lt;a href="https://react-day-picker.js.org/"&gt;react-day-picker&lt;/a&gt;&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;No&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Yes (either manual or moment.js))&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;3.7kB&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;None&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The remaining options are almost the same. Finally, we can choose how many points in &lt;em&gt;easy to style&lt;/em&gt; we would take if we were to remove moment.js. Let's say it's 2. This will allow us to select the final winner 🎉&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;UX&lt;/th&gt;
&lt;th&gt;Mobile Friendly *&lt;/th&gt;
&lt;th&gt;Supports localization *&lt;/th&gt;
&lt;th&gt;Good documentation&lt;/th&gt;
&lt;th&gt;Bundle size&lt;/th&gt;
&lt;th&gt;Dependencies&lt;/th&gt;
&lt;th&gt;Easy to style&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/airbnb/react-dates/"&gt;react-dates&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (using moment.js)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;231kB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;None&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;&lt;a href="https://reactdatepicker.com/"&gt;react-datepicker&lt;/a&gt;&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;5&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Yes&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Yes (internally uses date-fns)&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;5&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;293.5kB&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;None&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;5&lt;/del&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;del&gt;&lt;a href="https://react-day-picker.js.org/"&gt;react-day-picker&lt;/a&gt;&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;No&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;Yes (either manual or moment.js))&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;3.7kB&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;None&lt;/del&gt;&lt;/td&gt;
&lt;td&gt;&lt;del&gt;4&lt;/del&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, doing swaps correctly requires experience and criteria, the more you use it, the better you'll get at it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 5: Documenting your decision 📖
&lt;/h2&gt;

&lt;p&gt;Once you are left with only one option. I'd recommend you add the information about why you chose this library for your teammates to understand why they are using this library. A good option is creating a markdown file where you document the consequence table and method you used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hbr.org/1998/03/even-swaps-a-rational-method-for-making-trade-offs"&gt;Even Swaps: A Rational Method for Making Trade-offs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>decisionmatrix</category>
      <category>libraries</category>
      <category>opensource</category>
      <category>evenswaps</category>
    </item>
  </channel>
</rss>
