<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Won</title>
    <description>The latest articles on DEV Community by James Won (@jwwnz).</description>
    <link>https://dev.to/jwwnz</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%2F869456%2Fa3cd1e32-8028-46a0-9d9c-9ba0ab7bf68a.png</url>
      <title>DEV Community: James Won</title>
      <link>https://dev.to/jwwnz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jwwnz"/>
    <language>en</language>
    <item>
      <title>JavaScript Hoisting: What It Is And Why It Was Implemented</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Wed, 24 May 2023 13:08:27 +0000</pubDate>
      <link>https://dev.to/jwwnz/javascript-hoisting-what-it-is-and-why-it-was-implemented-51ep</link>
      <guid>https://dev.to/jwwnz/javascript-hoisting-what-it-is-and-why-it-was-implemented-51ep</guid>
      <description>&lt;p&gt;Hoisting is a key concept in JavaScript that can cause unexpected behavior in your code if you're not aware of how it works.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code. - MDN&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Hoisting Variables
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;If you declare a variable after its first usage, this variable declaration is "hoisted" to the top of its scope.&lt;/li&gt;
&lt;li&gt;If you assign a value to the variable, then the order it is assigned is unchanged and is unaffected by the hoisting.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See the following simple example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myFunction() {
  console.log(myHoistedVariable); // undefined for ES5 and below
  var myHoistedVariable= 1;
  console.log(myHoistedVariable); // 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Since the declaration of &lt;code&gt;myHoistedVariable&lt;/code&gt; is hoisted, the first &lt;code&gt;console.log&lt;/code&gt; will attempt to print out the value (Note. the actual result will differ depending on if you use &lt;code&gt;var&lt;/code&gt;, let or const)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;console.log&lt;/code&gt; will print undefined as the assignment of the value 1 isn't moved along with the hoisting (Note. this is for ES5 only using &lt;code&gt;var&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The above example, basically is the same as the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myFunction() {
  var myHoistedVariable
  console.log(myHoistedVariable); // undefined for ES5 and below or ReferenceError for ES6 `let` or `const`
  myHoistedVariable = 1;
  console.log(myHoistedVariable); // 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note. ES5 v ES6&lt;/strong&gt;&lt;br&gt;
While hoisting technically still occurs with ES6, in practical effects you will be prevented from using it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ES5: If you are using var a hoisted value will return undefined . This behaviour is called Type 2 hoisting behaviour by MDN.&lt;/li&gt;
&lt;li&gt;ES6: For let and const declarations are also hoisted to the top of their scope, but they are not initialized with a value of undefined. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Practically, this means you cannot use a let or const variable before it's declared, or you will get a ReferenceError. This is called Type 3 hoisting behaviour by MDN.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you declare a JavaScript file with 'use strict'; this will mean that hoisting using var will throw a Type 3 ReferenceError. (See &lt;a href="https://www.digitalocean.com/community/tutorials/understanding-hoisting-in-javascript"&gt;this article from Digital Ocean&lt;/a&gt; for more info)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hoisting Functions
&lt;/h2&gt;

&lt;p&gt;Hoisting for functions get a bit more interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function declarations are hoisted to the top of their scope. This means that you can call functions before they are declared.
&lt;/li&gt;
&lt;/ul&gt;

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

function myHoistedFunction() {
    console.log("Hi I'm hoisted!");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Function expressions are not hoisted. This means that if you declare a function expression using const or let you cannot call the function before this declaration. This is also the case for arrow functions as they are also function expressions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why hoist at all??? 🤔
&lt;/h2&gt;

&lt;p&gt;If this all seems pretty random and unnecessary, it did to me too - especially hoisting variables.&lt;/p&gt;

&lt;p&gt;Why wouldn't you just enforce everyone to declare variables, functions and classes at the top of their scope? Even though this is largely corrected in ES6 and the move towards function expressions as the conventional norm (another hot topic for another day).&lt;/p&gt;

&lt;h3&gt;
  
  
  Historical reasons
&lt;/h3&gt;

&lt;p&gt;Digging into this a bit further I found this tweet from the archives:&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://twitter.com/aravind030792?ref_src=twsrc%5Etfw"&gt;@aravind030792&lt;/a&gt; var hoisting was thus unintended consequence of function hoisting, no block scope, JS as a 1995 rush job. ES6 'let' may help.&lt;/p&gt;— BrendanEich (@BrendanEich) &lt;a href="https://twitter.com/BrendanEich/status/522395336615428097?ref_src=twsrc%5Etfw"&gt;October 15, 2014&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;This &lt;a href="https://www.quora.com/Why-does-JavaScript-hoist-variables"&gt;article on Quora&lt;/a&gt; explains this further. **TL;DR **Brendan Eich when implementing JavaScript (AKA LiveScript) in 10 days wanted to avoid the painful top to bottom enforcement of function declarations in ML languages like Lisp.&lt;/p&gt;

&lt;p&gt;Brendan also followed up with a following tweet clarifying that var hoisting was unintended:&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://twitter.com/aravind030792?ref_src=twsrc%5Etfw"&gt;@aravind030792&lt;/a&gt; var hoisting was thus unintended consequence of function hoisting, no block scope, JS as a 1995 rush job. ES6 'let' may help.&lt;/p&gt;— BrendanEich (@BrendanEich) &lt;a href="https://twitter.com/BrendanEich/status/522395336615428097?ref_src=twsrc%5Etfw"&gt;October 15, 2014&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;From this context - the feature does make sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interpreter performance reasons
&lt;/h3&gt;

&lt;p&gt;When the JavaScript engine compiles code, it first goes through a process called parsing, where it breaks down code into smaller, more manageable pieces.&lt;/p&gt;

&lt;p&gt;By moving function declarations to the top of their scope before execution, the interpreter can avoid the need to search for the declaration of the function each time it is called. Instead, it can simply execute the function directly from memory, which can be faster and more efficient.&lt;/p&gt;

&lt;p&gt;To summarise, it appears there are two key benefits of Hoisting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Allow you to use function declarations before they are defined&lt;/strong&gt;. This allows you to organise where you put your function code regardless of where they are called as long as they are within the same scope.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improve the performance of the interpreter&lt;/strong&gt;. Because variable declarations are moved to the top of their scope during compilation this may reduce the time the JavaScript engine needs to parse the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some great resources on Hoisting/reading material related to the topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting"&gt;MDN docs on Hoisting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.bitsrc.io/what-is-javascript-hoisting-f0678208eb08#:~:text=Hoisting%20is%20JS's%20default%20behavior,only%20hoists%20declarations%2C%20not%20initializations."&gt;What is JavaScript Hoisting?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/15005098/why-does-javascript-hoist-variables/15014769#15014769"&gt;Stackoverflow discussion on hoisting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.quora.com/Why-does-JavaScript-hoist-variables"&gt;Quora: Why does JavaScript hoist variables?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://launchschool.com/books/javascript/read/introduction"&gt;A brief JavaScript history&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>hoisting</category>
    </item>
    <item>
      <title>The Importance of Doing Code Reviews</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Mon, 03 Apr 2023 10:31:55 +0000</pubDate>
      <link>https://dev.to/jwwnz/the-importance-of-doing-code-reviews-2p88</link>
      <guid>https://dev.to/jwwnz/the-importance-of-doing-code-reviews-2p88</guid>
      <description>&lt;p&gt;As a software engineering team, you want to produce high-quality code that is efficient, maintainable, and scalable. Achieving this goal is not just about writing code, it's also about reviewing it. Code review is an essential part of the development process, and it can help raise productivity in your team. In this article, we'll explore why code review is important and how it can help your team produce better software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is code review important?
&lt;/h2&gt;

&lt;p&gt;Code review is the process of reviewing code written by other team members to ensure that it meets certain standards, adheres to best practices, and is free of bugs and other issues. It's an essential part of the development process because it helps catch errors and bugs before they become bigger problems that could cause application failures or even security vulnerabilities. Here are some benefits of code review:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Finding bugs and errors: Code review helps identify bugs, errors, and other issues in the code. By reviewing each other's code, engineers can catch mistakes before they become bigger problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improving code quality: Reviewing code helps ensure that best practices are being followed, that the code is readable, maintainable, and efficient. This, in turn, leads to better-quality code that is easier to maintain and modify.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Knowledge sharing: Code reviews provide a great opportunity for engineers to learn from each other. By reading and reviewing code written by others, engineers can learn new techniques and approaches to coding that they can apply to their own work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encouraging collaboration: Code reviews encourage collaboration among team members. By reviewing each other's code, engineers can work together to solve problems, share knowledge, and improve the overall quality of the codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Meeting standards and requirements: Code reviews can help ensure that code meets industry standards, company guidelines, and regulatory requirements. This can help avoid compliance issues and legal problems down the line.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  10x teammate &amp;gt; 10x developer
&lt;/h2&gt;

&lt;p&gt;While the popular idea of the 10x developer may suggest that certain individuals can produce 10 times as much output as their peers, the reality is that producing high-quality code is a team effort. Even the most talented individual cannot produce high-quality code in isolation. &lt;/p&gt;

&lt;p&gt;Code review is an essential part of the development process not just rapidly programming, and it's critical to have a culture of frequent reviews in order to produce high-quality software. &lt;/p&gt;

&lt;p&gt;This means that it's more valuable to be a 10x teammate who can collaborate effectively, provide valuable feedback, and participate in code review than a 10x developer who works in isolation and produces code without seeking feedback and input from others. &lt;/p&gt;

</description>
      <category>github</category>
      <category>programming</category>
      <category>reviews</category>
    </item>
    <item>
      <title>Why you should create new GraphQL queries: How I caused an incident expanding an existing query and the lessons learned</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Sun, 04 Dec 2022 00:20:21 +0000</pubDate>
      <link>https://dev.to/jwwnz/why-you-should-create-new-graphql-queries-how-i-caused-an-incident-expanding-an-existing-query-and-the-lessons-learned-4okk</link>
      <guid>https://dev.to/jwwnz/why-you-should-create-new-graphql-queries-how-i-caused-an-incident-expanding-an-existing-query-and-the-lessons-learned-4okk</guid>
      <description>&lt;p&gt;I recently started a new job about a month ago and at my new company we use GraphQL.&lt;/p&gt;

&lt;p&gt;I'm fairly new to GraphQL. While I had dabbled with Graphql in a personal project years before I hadn't used it in a professional context.&lt;/p&gt;

&lt;p&gt;My impression over the past few weeks is that it is an amazing framework, and I especially love developer friendly features like &lt;a href="https://graphql.org/learn/introspection/"&gt;introspection&lt;/a&gt; to quickly identify backend API changes. Also I personally did not like using global state management systems like Redux, and GraphQL's caching really is a breath of fresh air.&lt;/p&gt;

&lt;p&gt;I didn't really have major issues using it over the past few weeks so I thought I was in the clear.&lt;/p&gt;

&lt;p&gt;Then I caused an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  The issue
&lt;/h2&gt;

&lt;p&gt;The funny thing was the incident was caused in production by feature flagged work. &lt;/p&gt;

&lt;p&gt;In a nutshell: &lt;/p&gt;

&lt;p&gt;I expanded an existing GraphQL query to get additional data. This query was used once somewhere else but this existing usage caused CPU utilisation in the backend to skyrocket, leading to: (1) queries adding huge load on the backend and (2) increased query response delays by a factor of upto 10-20x.&lt;/p&gt;

&lt;p&gt;Dissecting the issue a bit more there were three front-end factors that led to potency of the problematic code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Potentially large data&lt;/strong&gt;: The attributes that I added on to the query were getting back nested arrays of data. Depending on the complexity of the query subject this led to huge data coming back for the existing usage of the query.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Polling&lt;/strong&gt;: I didn't know at the time but the query in question was being aggressively polled to refresh stale data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Existing usage of the query&lt;/strong&gt;: The common usage of the page where this query was used is one of the most popular pages and one where any given user can have multiple versions of this page open in tabs at once. This meant that the issues in (1) and (2) were amplified multiple-fold.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Triaging
&lt;/h2&gt;

&lt;p&gt;By the time this reached my attention the problem was well-dissected and my PR had been identified as the cause. Lucky for me our company has a great incident management system and thankfully this allowed the problem to be identified quickly and incisively.&lt;/p&gt;

&lt;p&gt;While the issue end-user impact was a slightly degraded experience, this was a potentially critical issue that needed to be dealt with before higher traffic hit our application.&lt;/p&gt;

&lt;p&gt;When I jumped on a call with a staff-engineer and discussed the data I realised almost instantly what had happened and that my expanded query was polling the backend CPU with exponentially dense data like a cancer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;We quickly made a plan to revert my change to the existing query and to split off the new behaviour to a new query that would be fully cordoned off from production. The new query would not be polled.&lt;/p&gt;

&lt;p&gt;I actioned this and we immediately noticed the CPU utilisation drop back to normal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Incorrect assumptions
&lt;/h2&gt;

&lt;p&gt;In retrospect, the problem seemed so obvious. However at the time I naively thought I was making the right decision to expand the existing query:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The existing query was getting a type of data that was consistent with the existing query. I mistakenly thought that the query could be enhanced with the new attributes that I was trying to get. I had a rough idea about the GraphQL caching so thought it would be great to get this data earlier in the existing usage then a subsequent query to get this data would not be required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I didn't realise we polled so aggressively. In most products I have worked on in the past polling was used rarely and only where absolutely necessary, I made an assumption that this was the case here. I neglected to check this assumption before checking in the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;A couple of lessons that I took away from this experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make new GraphQL queries by default&lt;/strong&gt;. Where there is a new usage, by default creating a new query makes sure that unintended consequences to existing usages like here do not happen. This is especially important for feature flagged features - no new feature flag feature should ever affect existing production features or behaviour. Fight the temptation to tack on attributes to existing queries.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2 &lt;strong&gt;Test new code in staging throughly to see the GraphQL query requests and responses&lt;/strong&gt;. I did check, but only with subjects with small data and definitely not long enough to see the impact of polling. If I had (1) tested a subject with a large amount of data and (2) waited for the polling to kick in I would've realised pretty quickly that the combination of frequent polling and large response sizes would cause issues.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Beware of polling&lt;/strong&gt;, don't use it unless required and especially beware of altering existing queries that use polling.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Power of GraphQL: Buffet of queries
&lt;/h2&gt;

&lt;p&gt;A huge lesson for me was to be precise with GraphQL queries. It is vital to make sure that your query is targeted and get only what you need.&lt;/p&gt;

&lt;p&gt;One of our leading front-end engineers put it perfectly by likening using GraphQL to going to a buffet. &lt;/p&gt;

&lt;p&gt;You shouldn't try to get all the food (aka. attributes) you want in one plate (aka. query). There is absolutely no need as GraphQL handles the caching of the data received. Instead you should try to be incisive in the fresh data that you need specifically for the purpose of using that query when you need it.&lt;/p&gt;

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

&lt;p&gt;So long-story short I caused an incident by tacking on new data to an existing query. Lucky for me I only caused a slightly degraded experience for users for a short period of time it was a huge learning experience that I will take to heart.&lt;/p&gt;

&lt;p&gt;I learned massive lessons on using GraphQL, and the biggest being to make new queries each time you have a new usage to consume data from GraphQL.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>graphql</category>
      <category>programming</category>
    </item>
    <item>
      <title>Trust The Process</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Sun, 11 Sep 2022 09:19:25 +0000</pubDate>
      <link>https://dev.to/jwwnz/trust-the-process-2epd</link>
      <guid>https://dev.to/jwwnz/trust-the-process-2epd</guid>
      <description>&lt;p&gt;I was recently preparing giving a talk to university students. As I prepared a number of tips for people in the same shoes a couple years ago I was reminded of the time when I was learning to code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning to program is not easy
&lt;/h2&gt;

&lt;p&gt;At least it wasn't easy for me.&lt;/p&gt;

&lt;p&gt;Almost exactly 5 and a half years ago I gave up my plushy office job as a lawyer and jumped into the world of programming.&lt;/p&gt;

&lt;p&gt;At first learning to code was excruciating. I remember struggling a lot with basic concepts. Things like reference equality in JavaScript or inheritance in object oriented programming seemed so unnatural to me.&lt;/p&gt;

&lt;p&gt;I remember getting frustrated that I wasn't learning fast enough. That I was somehow 'falling behind'. That I wasn't getting 'results'. I started to doubt whether I had the aptitude for programming.&lt;/p&gt;

&lt;p&gt;But over time with enough trial and error I realised that my thinking had been flawed.&lt;/p&gt;

&lt;p&gt;It wasn't that I wasn't good enough, it was because I didn't trust the learning process.&lt;/p&gt;

&lt;h2&gt;
  
  
  The process is the most important thing in programming
&lt;/h2&gt;

&lt;p&gt;The biggest breakthrough for me when learning to program happened about two months in after my career shift.&lt;/p&gt;

&lt;p&gt;The class I was learning programming was holding a hackathon. We were to make a game, any game. I decided to try to make a 2D game Pokemon jumping game. Using canvas and JavaScript I managed to hack together a half-decent game (* with poor collision detection). &lt;/p&gt;

&lt;p&gt;But the most important thing was during the process I enjoyed myself and learned a whole bunch. I probably didn't understand 90% of the code that I wrote and it was ugly code. &lt;/p&gt;

&lt;p&gt;But in the process of problem solving I realised how enjoyable it was. From that day on I tried to do program or learn something about programming everyday that fascinated me. And over the next few months I started enjoying the process of learning over trying to reach whatever arbitrary goal that I thought I needed to reach.&lt;/p&gt;

&lt;p&gt;It definitely wasn't fast. Somethings just took a lot of time to process. And somethings didn't become clear until many years on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Secret
&lt;/h2&gt;

&lt;p&gt;But therein lied the secret. The enjoyment of the process of learning was the thing I had lacked. In my tunnel-visioned desire to quickly become something I missed the fact that learning to program to take time.&lt;/p&gt;

&lt;p&gt;The thing with programming it is not something you can just pick up and gain mastery. As with most things, but especially in programming good things take time. &lt;/p&gt;

&lt;p&gt;The process matters. And the time you spend matters.&lt;/p&gt;

&lt;p&gt;Over the five years that followed I re-realised this again and again. In programming, learning needs to be constant, consistent. To be a good programmer means you need to be willing to learn and re-learn again and again and be fundamentally interested in what you are learning. That's the only way you can get good and stay good.&lt;/p&gt;

&lt;p&gt;The great thing about programming in comparison to other professions is that over time you see yourself level up.&lt;/p&gt;

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

&lt;p&gt;For anyone struggling I really encourage you to not to lose heart. &lt;/p&gt;

&lt;p&gt;Yes programming can be hard, especially at the start. But if you keep at it and slow down to enjoy the process, you will get better and better until eventually before you know it you will be great.&lt;/p&gt;

&lt;p&gt;Just make sure when you get there to not forget to keep learning and continue with the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Trust the process.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>Spreading arrays in a resilient way using JavaScript/TypeScript</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Sat, 10 Sep 2022 08:55:30 +0000</pubDate>
      <link>https://dev.to/jwwnz/spreading-arrays-in-a-resilient-way-using-javascripttypescript-1990</link>
      <guid>https://dev.to/jwwnz/spreading-arrays-in-a-resilient-way-using-javascripttypescript-1990</guid>
      <description>&lt;p&gt;Spreading is a really handy technique that we JavaScript developers use daily. &lt;/p&gt;

&lt;p&gt;Some common usages are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When constructing a new array using the existing array items immutably.&lt;/li&gt;
&lt;li&gt;When updating or adding items to an array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We see code like the following often:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const originalArray = [a: {count: 1}, b: {count: 2}, c: {count: 3}]

const newArray = [...originalArray, a: { count: 10}]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Perils of spreading in JavaScript
&lt;/h2&gt;

&lt;p&gt;But it can be fraught with peril when the spread array can be undefined. &lt;/p&gt;

&lt;p&gt;Just like with destructuring undefined values, spreading undefined values can be the source of unexpected bugs.&lt;/p&gt;

&lt;p&gt;For example examine the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const originalArray = couldBeStringArrayOrUndefined()

const newArray = [...originalArray]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Perils in TypeScript
&lt;/h2&gt;

&lt;p&gt;This same code is further complicated in TypeScript. You will be faced with an error&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const originalArray = couldBeStringArrayOrUndefined()

const newArray: string[] = [...originalArray]

Type 'string[] | undefined' must have a '[Symbol.iterator]()' method that returns an iterator.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;The solution is quite simple.&lt;/p&gt;

&lt;p&gt;If you know the value could be undefined add an OR empty array.&lt;/p&gt;

&lt;p&gt;So for the above code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In Vanilla JS
const newArray = [...originalArray || []]

// In TypeScript
const newArray: string[] = [...originalArray || []]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solution makes intuitive sense, as this code is simply specifying that if the spread array is undefined an empty array will be spread (and thus no items spread).&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveat
&lt;/h2&gt;

&lt;p&gt;This solution comes with the caveat that wherever possible it is better to make sure an undefined value is handled further up the chain.&lt;/p&gt;

&lt;p&gt;For example if your undefined value can come from an asynchronous call, it might be better to explicitly get your promise to resolve to an empty array &lt;code&gt;[]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This will have the same effect as the solution above, but also give you the confidence of being able to test the value being added in.&lt;/p&gt;

&lt;p&gt;But this isn't always possible, so don't feel bad if you have to resort to the &lt;code&gt;...spreadArray || []&lt;/code&gt; combo when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Using the spread operator is great!&lt;/li&gt;
&lt;li&gt;But be careful of spreading undefined values.&lt;/li&gt;
&lt;li&gt;Use the simple &lt;code&gt;...spreadArray || []&lt;/code&gt; combo to make your code resilient to undefined values!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How we sped up the loading time of a critical experience by 3x</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Tue, 23 Aug 2022 08:56:00 +0000</pubDate>
      <link>https://dev.to/jwwnz/how-we-sped-up-the-loading-time-of-a-critical-experience-by-3x-34nl</link>
      <guid>https://dev.to/jwwnz/how-we-sped-up-the-loading-time-of-a-critical-experience-by-3x-34nl</guid>
      <description>&lt;p&gt;Recently we sped up the loading time of a critical experience in our application by over 3x. &lt;/p&gt;

&lt;p&gt;Here's how we did this and some of the learnings I gained from the experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;The repo in concern is a front-end platform that is the main customer-facing product of our company. This platform uses React, NextJS and Redux.&lt;/p&gt;

&lt;p&gt;In this application there is a really important experience - the user table where users can set various settings of a particular user. User information is also used throughout our application.&lt;/p&gt;

&lt;p&gt;There were three concepts of user in our application:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Auth0 user&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the codebase was first built, it relied on Auth0 to store and provide permission role of the user. Over time further metadata was added onto the user in Auth0. These attributes played important roles in our application as users with different permission roles have different experiences within our application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The application 'member'&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was an overlapping but slightly different concept of a user. This contained attributes about a particular user of a platform regardless of the permission role and was stored in our own DynamoDB table. For example an important attribute was data role which determines how the processing of the user's data is done. It also included information like email and other personal attributes about the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The combined 'user state'&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because the user was incomplete without the combination of the first two user concepts, there was a third important concept: the user state. &lt;/p&gt;

&lt;p&gt;This state was a combination of (1) Auth0 information and (2) member. This was stored in Redux global state.&lt;/p&gt;

&lt;p&gt;When the table first loaded up there was logic to retrieve and store the data together as a combined object. For the purposes of the application, this was the most important source of information as this was relied on by all experiences needing user information.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;You probably have a good idea now where this is going.&lt;/p&gt;

&lt;p&gt;This setup was great at first as there was no duplication of data and needing to keep things in sync. However, as experiences became more complex and the need to retrieve and update user information expanded we started building significant logic that cross-weaved between the three user data concepts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Any user related action required complex logic to check and update the two sources of truth and update the local state. There was additional logic specifically to update the local state in a way where you didn't need to actually retrieve the two sources of truth (to prevent the long retrieval wait times).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To make this concept even more complicated, some forms of users didn't have 'member' attributes. This led to situations where most members were Auth0 users, but not necessarily so meaning there wasn't a direct way to combine users through a 'member' id.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Long-story short this setup worked, mostly. There were two huge tradeoffs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Long load time: It was immensely long the first time (5000ms plus). Then afterwards it was mostly immediate when it relied on the combined user state. But in some situations a full refresh was required and yes, this required the full 5000ms+.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overtime it became almost impossible to add even the basic interaction for a user without having issues crop up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When bugs with users occurred patching resulted in adding layers to an already complex web of logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Our solution
&lt;/h2&gt;

&lt;p&gt;With the frequency of issues we decided to act. Because data relating to a user touched all corners our application it got to a point where we just couldn't ignore the underlying cause.&lt;/p&gt;

&lt;p&gt;We pinpointed the issue to be the two sources of truth, and the complexity that it spawned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single source of truth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We transitioned to storing all the combined attributes of a single concept of a 'member' (including the concept of the prior 'member' and auth0 user) directly to a DynamoDB table.&lt;/p&gt;

&lt;p&gt;This meant that we had one source of truth, the 'member'. &lt;/p&gt;

&lt;p&gt;We got rid of the situation of a user without member information and by default made sure 'member' always had a unique id and this could be used to identify a members full details (including former 'member' and Auth0 user details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amending the backend and databases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This required massive changes to our backend (both our API spec and micro-service connecting to our 'member' table), a new database and carefully coordinate database migration to transition and combine data sources to the new DynamoDB database. This was a huge amazing effort on the parts of our lead engineer who led the data and backend changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refactoring the front-end&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the front-end we went through a painstaking refactor. This included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewriting out the existing user table logic&lt;/li&gt;
&lt;li&gt;Identifying everywhere we used 'member', 'user' or the local combined state and rewriting the logic to use the now combined concept of 'member'.&lt;/li&gt;
&lt;li&gt;All the combined logic to retrieve, create, or update users were rewritten. We still needed to update Auth0 when the permissions changes - however we could do this in a way that we could rely on the 'member' state to be in sync with this update.&lt;/li&gt;
&lt;li&gt;The concept of the combined user state was erased and now we simply retrieve the updated 'member' list when an update takes place.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;We don't need to wait on the 5000ms to combine data data anymore. This data is retrieved on the first login and when there is a reload it is under 1500ms.&lt;/li&gt;
&lt;li&gt;Much more simpler code - for example one Redux action was over 400 lines with a bunch of &lt;code&gt;switch&lt;/code&gt; and &lt;code&gt;if&lt;/code&gt; statements. These have been rewritten to be much, much smaller with minimal conditionals.&lt;/li&gt;
&lt;li&gt;Less bugs and much more understanding about the concept of a user. The time saved as a result is exponentially growing in our dev team.&lt;/li&gt;
&lt;li&gt;We deleted thousands of lines of code.&lt;/li&gt;
&lt;li&gt;We got this done on time! Not a small feat given the scope of changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learnings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Re-evaluate code often&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes we make decisions that was entirely appropriate at the time but simply didn't grow with your needs. By regularly evaluating areas of the code you know are problematic for it's viability, it helps you make painful decisions that are worth it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Simple is always best&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some of the logic that existed before our refactor was quite clever. However, it create complexity that was really not needed. For example having a combined local user state that had complex logic around updating accurately without retrieving the actual updated information sources of truth. Just simplifying to use the actual source of truth we could just delete this entire logic and use the data as is without any layers on top.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Refactoring is a fact of life&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes we do so much to avoid a refactor. Yes, it's painful but it's sometimes better to face up to it and do the work. If it's an important piece of logic, the sooner the less complex the work will be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. TypeScript is awesome&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Knowing that we would be pretty much rewriting the entire logic for users, I casually added in TypeScript for our repo before we got started with the refactor. I am so thankful I did this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We were able to eliminate a lot of issues such as methods that converted objects into new objects. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It also allowed us to code with confidence knowing that the new objects coming through could be relied upon to contain the attributes that we needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are thinking of adopting to TypeScript (and especially if you are contemplating a refactor like us 😂) I'd highly recommend it as without it we would have definitely struggled more than we did.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>webdev</category>
      <category>refactoring</category>
      <category>programming</category>
    </item>
    <item>
      <title>How PR Wait time can impact contributor experience with open source repos</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Tue, 23 Aug 2022 07:11:03 +0000</pubDate>
      <link>https://dev.to/jwwnz/how-pr-wait-time-can-impact-contributor-experience-with-open-source-repos-24i</link>
      <guid>https://dev.to/jwwnz/how-pr-wait-time-can-impact-contributor-experience-with-open-source-repos-24i</guid>
      <description>&lt;p&gt;My colleague from &lt;a href="https://www.multitudes.co/"&gt;Multitudes&lt;/a&gt; Jenny Sahng wrote a great &lt;a href="https://medium.com/gitconnected/how-does-pr-review-wait-time-affect-your-open-source-project-d79bd0af0ea3"&gt;medium blog post&lt;/a&gt; about her research delving into PR wait time in open source projects.&lt;/p&gt;

&lt;p&gt;If you work on open source projects or am interested in the impact that review wait time can have on contributors I'd highly recommend giving this a read!&lt;/p&gt;

&lt;p&gt;Read here: &lt;a href="https://medium.com/gitconnected/how-does-pr-review-wait-time-affect-your-open-source-project-d79bd0af0ea3"&gt;"How does PR review wait time affect your open source project?"&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why you should put effort into your Pull Request description</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Mon, 22 Aug 2022 07:38:00 +0000</pubDate>
      <link>https://dev.to/jwwnz/why-you-should-put-effort-into-your-pull-request-description-p70</link>
      <guid>https://dev.to/jwwnz/why-you-should-put-effort-into-your-pull-request-description-p70</guid>
      <description>&lt;p&gt;Pull Requests are the primary way new code is proposed, reviewed and merged. We know that Pull Requests are important. &lt;/p&gt;

&lt;p&gt;But programmers put in varying levels of effort in writing Pull Request descriptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The minimal effort PR
&lt;/h2&gt;

&lt;p&gt;An example of a minimal effort PR could be:&lt;br&gt;
&lt;/p&gt;

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

Added column feature to table.

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

&lt;/div&gt;



&lt;p&gt;It doesn't give any context why the change was made, nor the rationale, nor give any hints about what behaviours has changed or even give a link to an issue tracker to allow viewers to find this information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this may be occurring
&lt;/h2&gt;

&lt;p&gt;It can be easy for us programmers to focus on the code, and see Pull Requests as the annoying but necessary step to get the code up for review. &lt;/p&gt;

&lt;p&gt;We can make the mistake in thinking PRs are simply perfunctory thing and the content's doesn't matter.&lt;/p&gt;

&lt;p&gt;We may think &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"If they are curious they will ask questions"&lt;/li&gt;
&lt;li&gt;Or "they can search up the related ticket if they are curious".&lt;/li&gt;
&lt;li&gt;Or "What's the point, once it's merged it's &lt;strong&gt;&lt;em&gt;history&lt;/em&gt;&lt;/strong&gt; anyway".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But this kind of thinking is short-sighted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why careless PR content is harmful
&lt;/h2&gt;

&lt;p&gt;Yes, reviewers should ask questions if things don't make sense. But you are:&lt;/p&gt;

&lt;p&gt;A. Making it harder on your reviewers than it needs to be; and&lt;br&gt;
B. More importantly, you are removing the valuable context about why a piece of code was added and links to important information.&lt;/p&gt;

&lt;p&gt;I'll dig in a bit deeper about (B). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code rarely remains static.&lt;/strong&gt; It evolves and over time it morphs into something very different from when it was originally concepted and created. The same piece of code may be based on different knowledge at different points in time.&lt;/p&gt;

&lt;p&gt;There will be situations in the future that you or others need to understand why a certain code change was made. You can use git blame or history to find the code changes. But without proper PR descriptions the context is lost to history.&lt;/p&gt;

&lt;p&gt;This kind of thinking is short-sighted.&lt;/p&gt;

&lt;p&gt;If you write proper descriptions however, this rich information and context can be used by future programmers to understand the rationale behind your code and make quicker and more quality code decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips
&lt;/h2&gt;

&lt;p&gt;Some things that have worked for me are to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a &lt;strong&gt;descriptive title&lt;/strong&gt; for the PR
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat [ENG-1234]: Add ability to add feedback column to PR table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specify at a high level all the important changes&lt;/strong&gt; made in your description. You don't need to get into detail but at least list at a high level, enough to give context to the corresponding code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This PR adds the following updates to PR Table:
1. Users can now add a column to add feedback.
2. Touch support.
3. Updates to unit tests to reflect new interactions.
4. Update third-party packages to add animation support.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Where there is &lt;strong&gt;something of note&lt;/strong&gt; about the code changes specify this in the PR.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Note. This PR results in visual regressions to support better touch targets. See the images below...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Include the &lt;strong&gt;rationale&lt;/strong&gt; behind the code. You don't need an essay but a short line behind why the feature was added.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To allow users to add a column to add feedback information. For more information about the rationale check out this `[slack link](url)`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Include a &lt;strong&gt;link to the issue tracker ticket&lt;/strong&gt;. If you decide to not include a rationale this is doubly important.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[https://this-is-an-issue-tracker.com/eng-1234](https://this-is-an-issue-tracker.com/eng-1234)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;(For front-end) Where visual changes are made include an &lt;strong&gt;image or video&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a PR template to encourage inclusion of information like description, rationale and PR Checklist.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>programming</category>
    </item>
    <item>
      <title>Apply DRY to knowledge, not source code</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Sun, 21 Aug 2022 07:05:31 +0000</pubDate>
      <link>https://dev.to/jwwnz/apply-dry-to-knowledge-not-source-code-3df6</link>
      <guid>https://dev.to/jwwnz/apply-dry-to-knowledge-not-source-code-3df6</guid>
      <description>&lt;p&gt;DRY or Do Not Repeat Yourself, is an often repeated important concept in programming. Most of us try our utmost to prevent writing repetitive code using methods like abstraction to reuse code across our codebases.&lt;/p&gt;

&lt;p&gt;However, I'm sure all of us has come across situations where the code is over-abstracted. For instance a function shared across multiple different areas of code. The logic is perhaps 60-90% the same. However this function is massive with multiple case scenarios that do all manners of different logic with the last 10-40%. We know deep down something is wrong, but hey - we shouldn't repeat code right?&lt;/p&gt;

&lt;p&gt;Wrong.&lt;/p&gt;

&lt;p&gt;I've started reading the Pragmatic Programmer and I've finally been able to put my finger on the reason why this common scenario feels so wrong.&lt;/p&gt;

&lt;p&gt;As programmers we focus on source code and making sure we DRY our code. But DRY wasn't supposed to be for source code. It is supposed to prevent code with the same knowledge being repeated. There is a subtle difference, but it's a definitive one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems of focusing on DRY for source code in isolation
&lt;/h2&gt;

&lt;p&gt;Some code may have similar internals or even portions which are identical. But these differences may be coincidental. &lt;/p&gt;

&lt;p&gt;For example code for logging in for a buyer user seems very similar to logging in for a seller. The code might even be 90% similar. But because of the 10% differences the actual knowledge being captured is significantly different. If you simply add many case scenarios (using switch cases or &lt;code&gt;if&lt;/code&gt; statements) you are creating code that will be very difficult to debug due to being tightly coupled. Also what happens if you add a third type of user and a fourth such as an auctioneer and agent?&lt;/p&gt;

&lt;p&gt;I've added a quick example below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const logInUser = (invitationType, user) =&amp;gt; {
    const message = `Hello ${user.userName} from ${user.org}`
    const locale = user.locale

    if (invitationType === 'buyer') {
        // Get data from buyer member table and set state
        // Make API call to get list of possible purchase options to display on welcome page
    } 
    if (invitationType === 'seller' {
        // Get data from seller member table and set state
        // Make API calls to get summary of buyers interested to notify user

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

&lt;/div&gt;



&lt;p&gt;You should instead focus on applying DRY to knowledge. If the  requirements, flow and needs are different it requires different code even though portions may seem to be DRY. Focus on the big picture. If you apply DRY dogmatically to source code you will make tightly-coupled code which should not be coupled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some disclaimers
&lt;/h2&gt;

&lt;p&gt;Of course there are ways you can share code without coupling in the above situation. You can have two separate functions dealing with each legitimately different flows. You can then safely abstract parts of shared code that doesn't couple the two different scenarios together. Then both code blocks that are capturing different knowledge can safely share this generic code.&lt;/p&gt;

&lt;p&gt;eg.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const generateMessageForInvitedUser = (user) =&amp;gt; `Hello ${user.userName} from ${user.org}`

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

&lt;/div&gt;



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

&lt;p&gt;Don't dogmatically apply DRY to source code. Have a think about the knowledge that a code block captures. Make sure to apply DRY to code that repeats knowledge. However if some source code is similar or has identical parts, check whether these two different code blocks are capturing different knowledge if so think twice before applying DRY.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The importance of being descriptive when naming</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Tue, 16 Aug 2022 10:03:00 +0000</pubDate>
      <link>https://dev.to/jwwnz/be-descriptive-when-naming-33m0</link>
      <guid>https://dev.to/jwwnz/be-descriptive-when-naming-33m0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;br&gt;
&lt;strong&gt;Phil Karlton&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;TL;DR: Don't overthink and just be as descriptive as you can when naming code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Naming things is hard. For example. When my wife was pregnant with our daughter we agonised for months over her name before coming up with her name and we still aren't sure if we picked right. What if she doesn't like her name when she grows up?&lt;/p&gt;

&lt;p&gt;Naming code can almost seem just as hard. We think '&lt;em&gt;there has to be a perfect name to give this code justice&lt;/em&gt;'. We think that it has to be clever, memorable. concise and snappy. &lt;/p&gt;

&lt;h2&gt;
  
  
  Some common pitfalls
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We can try to be too clever and end up with some obscure name
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const exoticOptimiser = () =&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Or we can try to use some clever reference.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const iWantToBeTheVeryBest = () =&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We also see a lot of shorthand. Some are acceptable like event-handlers eg.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(e) =&amp;gt; {} // e for 'event'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Some are just pure laziness
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const myLazyFunction = (a, b) =&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But all jokes aside poor naming has terrible consequences. I've seen some horrid naming in my short career, as I'm sure all of us have. Debugging and working with poorly named code is an avoidable nightmare.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The importance of good naming&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It's very likely that at some point in the future you won't be around to explain why you named a function in a certain way.&lt;/p&gt;

&lt;p&gt;Even if you are still there, you may forget why a function or some code was programmed in a certain way.&lt;/p&gt;

&lt;p&gt;If the name was formulated poorly there is a large likelihood you may lead the developer down rabbit holes.&lt;/p&gt;

&lt;p&gt;For example, what would you think if you saw this function?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const calcAB = (a,b) =&amp;gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calculate what? Is it even calculate? What is this function doing with a and b? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sure&lt;/strong&gt; you can read the code, but what if the code is 200 lines long? You've already wasted an opportunity to clearly identify the purpose and functionality of the function.&lt;/p&gt;

&lt;p&gt;Imagine instead you saw this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const calculateTheDistanceBetweenPoints = (pointA, pointB) =&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, it's much longer but it's readable and clear and descriptive. Even naming the parameters as &lt;code&gt;pointA&lt;/code&gt; is so much more clear than just saying &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I think is the right way&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Naming code isn't like naming a baby. You don't know how the baby will turn out once they grow up! But &lt;strong&gt;you know exactly what the code is supposed to do&lt;/strong&gt; (or at least I hope you do!). You have all the ingredients to write a good name.&lt;/p&gt;

&lt;p&gt;My 2c is that it's &lt;strong&gt;&lt;em&gt;best to be as descriptive as you can&lt;/em&gt;&lt;/strong&gt;. Describe the code. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If it is a variable call it exactly what it is. &lt;/li&gt;
&lt;li&gt;If it is a variable describe what it's supposed to do. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Forget being concise. Focus on being precise.&lt;/p&gt;

&lt;p&gt;You may end up with names that are quite long. But this is so much better than a name that is concise but obscure. &lt;/p&gt;

&lt;p&gt;If it is too obscure and you can't think of a good name, maybe it is actually indicating code smell and your function is not very good. If so great! You should refactor :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps that I follow
&lt;/h2&gt;

&lt;p&gt;Some steps that I follow to make sure that naming leaves a legacy and not a nightmare are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Be descriptive about what the code does.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review the name and make sure that it can't be interpreted in multiple ways.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For especially complicated functions, I specifically ask for feedback about the name in code reviews.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Write names that are descriptive, even if it is long! Remember that code is supposed to be readable - if it isn't it is bad code and naming is huge factor in determining if code is readable.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>TIL: Template Strings used with a function</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Tue, 16 Aug 2022 09:18:00 +0000</pubDate>
      <link>https://dev.to/jwwnz/til-template-strings-used-with-a-function-12ob</link>
      <guid>https://dev.to/jwwnz/til-template-strings-used-with-a-function-12ob</guid>
      <description>&lt;p&gt;ES6 introduced the handy Template literals that you probably use day-to-day to avoid string concatenation. &lt;/p&gt;

&lt;p&gt;But what you may not know is that you can parse these template literals with a function.&lt;/p&gt;

&lt;p&gt;This feature is called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates"&gt;Tagged templates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The concept is simple. You can pass an interpolated template literal into a function call.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The resulting function's first parameter is an array of the strings in the interpolated string.&lt;/li&gt;
&lt;li&gt;The subsequent parameters are the interpolated values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const exampleFunction = (testStringsArray, interpolated1, interpolated2) =&amp;gt; console.log(interpolated2, interpolated1, testStringsArray[0])

const value1 = "B"
const value2 = "C"

exampleFunction`A ${value1} ${value2}`

// Result is "C B A"

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

&lt;/div&gt;



&lt;p&gt;This might not be something we use day-to-day but it may be quite handy for package builders and possibly creating dynamic CSS values.&lt;/p&gt;

&lt;p&gt;The one place that I have seen it used this in is &lt;a href="https://styled-components.com/"&gt;styled components&lt;/a&gt;, although this is in hindsight - I didn't realise I was using this feature until I recently learned about what tagged templates were!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Reflections: Take care when adding dependencies</title>
      <dc:creator>James Won</dc:creator>
      <pubDate>Mon, 15 Aug 2022 08:43:52 +0000</pubDate>
      <link>https://dev.to/jwwnz/reflections-take-care-when-adding-dependencies-3c0b</link>
      <guid>https://dev.to/jwwnz/reflections-take-care-when-adding-dependencies-3c0b</guid>
      <description>&lt;p&gt;Today we ran into a problem where an abandoned dependency was blocking our ability to update React.&lt;/p&gt;

&lt;p&gt;The dependency was added nearly a year ago as our company quickly built and released features.&lt;/p&gt;

&lt;p&gt;It fits a specific scenario perfectly, and I can definitely see how the developers working on it at the time saved a lot of time in the short-run to release according to spec.&lt;/p&gt;

&lt;p&gt;However, the package has been long abandoned. In fact it hasn't been updated for 3 years. It was never an official package to begin with. While it was a shortcut a long time ago, now it has saddled us with technical debt that can only be addressed either through a significant rewrite or abandoning the feature in its current form.&lt;/p&gt;

&lt;p&gt;What's worse is that this package is only used in one place. The code implementing this is also non-trivial meaning that we built a relatively complex bit of code on top of this now defunct third-party library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-reflection
&lt;/h2&gt;

&lt;p&gt;While I didn't implement the code, I realised that this was a mistake that I could just have easily made.&lt;/p&gt;

&lt;p&gt;When I was early on in my programming journey I used to love adding packages. It's best not to create something if it is already created right?&lt;/p&gt;

&lt;p&gt;I've learned since then that this is not necessarily the case. There are good reasons and bad reasons to use packages. &lt;/p&gt;

&lt;p&gt;Packages that aren't updated die. And especially with UI based packages, they don't die a graceful death. Especially in the JavaScript ecosystem changes move so fast that being strategic is important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A couple of lessons:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Avoid using packages for shortcuts. Yes, they may help now but will you come back and undo the shortcut?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All packages are not created equal. If you have to use packages pick well-maintained ones, unless the package does not need to be updated. For example the package that caused us problems was clearly abandoned before we decided to use it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Especially avoid packages that themselves have a lot of dependencies that may conflict with your own eg. React.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask and ask your self again, do you really need that package? Eg. If the design you are seeking is so complex you need a package yet don't have the time to actually build it yourself, isn't it just better to build something simpler?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintaining dependencies take time and effort. Tech debt maintainence is important especially if you decide to rely on a package that is not well maintained.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That being said, the answer is not always to avoid dependencies. The key is to wary and make the decision with both eyes wide open.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
