<?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: Preston Pham</title>
    <description>The latest articles on DEV Community by Preston Pham (@prestonp).</description>
    <link>https://dev.to/prestonp</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%2F239914%2F583fa36b-09f8-4dd5-8a53-3e11ec9bd570.jpeg</url>
      <title>DEV Community: Preston Pham</title>
      <link>https://dev.to/prestonp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prestonp"/>
    <language>en</language>
    <item>
      <title>My 3 years using CAP Theorem in 3 minutes</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Fri, 05 Jul 2024 02:44:00 +0000</pubDate>
      <link>https://dev.to/prestonp/my-3-years-using-cap-theorem-in-5-minutes-1ojn</link>
      <guid>https://dev.to/prestonp/my-3-years-using-cap-theorem-in-5-minutes-1ojn</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUfftpmFmqMaiGZ-YpuDLOg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUfftpmFmqMaiGZ-YpuDLOg.png" alt="A colorful painting of a mango tree wearing a cap, in the style of 1800s, pixel art"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple and popular mention of the CAP Theorem in office work is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s not possible to have Consistency, Availability, and Partition tolerance at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are many other variants. I’m sure most engineers have heard at least one.&lt;/p&gt;

&lt;p&gt;The more complex but rarely mentioned explanation of the CAP Theorem would be from its original author, in this keynote from July 2000: &lt;a href="https://sites.cs.ucsb.edu/~rich/class/cs293b-cloud/papers/Brewer_podc_keynote_2000.pdf" rel="noopener noreferrer"&gt;Brewer PODC Keynote&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The most complex and almost never discussed is CAP’s proof. For example, this nicely written paper: &lt;a href="https://users.ece.cmu.edu/~adrian/731-sp04/readings/GL-cap.pdf" rel="noopener noreferrer"&gt;Brewer’s Conjecture And The Feasibility of Consistent, Available, Partition-Tolerance Web Services&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think the Simple CAP is not suitable to convey its meaning accurately, at least not enough for software development work, especially when decisions need to be made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Dangerously, decisions that require mentioning CAP are often important ones.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, the Complex CAP is too long and too technical. There are many details requiring an understanding of distributed system theory. In most cases outside research, we don’t actually need those. Needless to say, it is rarely used in offices.&lt;/p&gt;

&lt;p&gt;I seek something in the middle for my own use and came up with what I call “Sweet CAP.” It is not a single sentence, but four. Here they are:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;C in CAP is strong consistency.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;With many servers, P is always needed so we simply choose C or A.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A is preferred in most cases not involving money, together with eventual consistency.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Simplicity first, you may not need to worry about CAP at a small scale.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Certainly, saying all four at the same time is weird. I choose to use each sentence when necessary. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Jerry: Because of CAP, our service needs to shut down when we are doing this operation to maintain consistency.&lt;/p&gt;

&lt;p&gt;Me: Wait a second, we only need to shut down if we need strong consistency. Is it this case?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have used these in my work over the last three years in chats, talks, and design documents. My colleagues seem to be okay with it. Most don’t have a problem understanding the message I want to convey. Sometimes, it even ignites more enjoyable discussions.&lt;/p&gt;

&lt;p&gt;That’s why it is Sweet CAP.&lt;/p&gt;




</description>
      <category>captheorem</category>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
      <category>systemdesignconcepts</category>
    </item>
    <item>
      <title>5 tips to secure your weekends</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Wed, 27 Mar 2024 13:18:01 +0000</pubDate>
      <link>https://dev.to/prestonp/5-tips-to-secure-your-weekends-3hke</link>
      <guid>https://dev.to/prestonp/5-tips-to-secure-your-weekends-3hke</guid>
      <description>&lt;p&gt;After a successful release of a critical bug fix, I stood up from office desk to head home. Along the way, I couldn’t stop feeling so good about myself. There’s nothing quite like the feeling when people commend you as a Rockstar Engineer.&lt;/p&gt;

&lt;p&gt;Well, it was Friday evening and I had indeed accomplished some good work after all. Besides, my luggage was already packed, awaiting a planned trip to the beach for the next two days!&lt;/p&gt;

&lt;p&gt;The next day arrived, and I did make it to the beach. But my travel plan ended up in the gutter. My weekends free time disappeared like smoke.&lt;/p&gt;

&lt;p&gt;I found myself switching between the hotel desk, absolutely ill-equipped for work, and my bed; investigating why my bug fix ironically transformed into a new bug itself.&lt;/p&gt;

&lt;p&gt;“Stressful” and “annoying” were not enough to describe how I felt.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uBQYK5oi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AaRrl5b8R9X732Vkl" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uBQYK5oi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AaRrl5b8R9X732Vkl" alt="A colorful painting of a software engineer debugging with his laptop at home while thinking about lying on the beach drinking mango juice, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The event above happened about 5 years ago. Back then, I was the main engineer in charged with maintaining a critical ETL pipeline. Its result is the main inputs for a recommendation system generating huge sales in a top successful company product.&lt;/p&gt;

&lt;p&gt;From an outsider’s point-of-view, you are looking at an inexperience engineer tasked with overseeing a mission-critical software. Disasters are bound to happen.&lt;/p&gt;

&lt;p&gt;But I won’t talk about the technical solution in this post. I’m sure that it will be boring enough that you guys will close this browser tab before you even read half of it.&lt;/p&gt;

&lt;p&gt;Instead, I want to share the lessons I learned looking back at that event. Those lessons are distilled into the 5 Tips below to help you steer clear of the sad outcome.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Good Intention
&lt;/h3&gt;

&lt;p&gt;Please allow me 5 sentences before presenting the Tips.&lt;/p&gt;

&lt;p&gt;Readers coming from other professions may notice and wonder why we corporate engineers frequently have to work on weekends.&lt;/p&gt;

&lt;p&gt;Believe me when I say the root cause is our unreasonably high responsibility and expectation of our work. My thoughts were usually “Just a little bit more and I can save the business” or “Just a little bit more and I can deliver this mission critical feature today”.&lt;/p&gt;

&lt;p&gt;So if you see friends who are in the same situation, please support them. They didn’t mess up, they just had too much good intention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip #1: Release Policy
&lt;/h3&gt;

&lt;p&gt;This policy is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Never release on Friday afternoon or any afternoon before your day off.&lt;/li&gt;
&lt;li&gt;If you have to release in those forbidden times, always make sure roll-back is possible and convenient.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your workplace doesn’t have similar policies, propose to your boss to make it available. If you cannot do that, keep this to yourself and use these following tricks to avoid violating it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I cannot finish it in time to today without making sure everything works as expected, but I will definitely finish on the next monday.&lt;/li&gt;
&lt;li&gt;I can try to release today but there is a huge risk of failure and we have no plan B.&lt;/li&gt;
&lt;li&gt;Let me finish testing this code today so we can have a safe release on the next monday and be done with this feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We don’t deceive our colleagues or bosses. Please don’t do that. The point is to show valid reasons to delay the release. Usually, safety reasons are the most convincing.&lt;/p&gt;

&lt;p&gt;But sooner or later, there will be times when it is inevitable to release on Friday afternoon. Such as when the business promotion campaign is scheduled on weekends.&lt;/p&gt;

&lt;p&gt;In those cases, a roll-back mechanism is a must-have. And to have it, pay attention configurations before doing code change. The goal is to have a button or equivalents to revert the system back to the state before the release. Then make this button accessible when you are not at your office desk.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧯 Design for Backward Compatibility so you can roll-back safely.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having a colleague doing this for your also works. But please let him/her knows beforehand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fsq8Hh0j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AOnPArMfGfzAqTYC9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fsq8Hh0j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AOnPArMfGfzAqTYC9" alt="A colorful painting of a mango shop with a sign saying the shop is closed on friday, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip #2: Don’t count weekends into estimates
&lt;/h3&gt;

&lt;p&gt;It may sounds strange to many people to count 2 days from weekends into estimates. But once in a while, it is very tempting to do so.&lt;/p&gt;

&lt;p&gt;After all, saying out loud to everyone in the meeting that you can finish the task on Monday feels more superior than on Wednesday. Doing so briefly transforms us into a Rockstar Developer with an additional benefit of good impression on the boss.&lt;/p&gt;

&lt;p&gt;But hear me out, don’t ever do this. To see why, consider these scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your kids want to go swimming pool with you, thrice a day.&lt;/li&gt;
&lt;li&gt;Your flight is delayed.&lt;/li&gt;
&lt;li&gt;Your dog eats weird things and you need the vet’s help to make sure the poor soul is ok.&lt;/li&gt;
&lt;li&gt;Your girl friend calls asking to go to the amusement park together, immediately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are unexpected scenarios that can happen any day of the week, including those two precious weekends. Thus, we want to avoid putting ourselves in the situation of having to choose between these events and finishing the committed task.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The consequence of breaking the task estimate is losing trust and ruining the project timeline.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--paEgFgoc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2ASnm3KQ8bmsQNIYFT" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--paEgFgoc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2ASnm3KQ8bmsQNIYFT" alt="A colorful painting of a desk and a planner calendar with mango illustration, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip #3: Ignore non-urgent chats
&lt;/h3&gt;

&lt;p&gt;Urgent Chats are about live issues and require immediate investigation.&lt;/p&gt;

&lt;p&gt;We will only allow those messages to have our attention. I use these 3 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify chat channels or threads that contains Urgent Chats.&lt;/li&gt;
&lt;li&gt;Setup notification only for those channels. Make sure the notification can reach your phone timely. Additionally, allow it to get your immediate attention by setting a unique ringtone.&lt;/li&gt;
&lt;li&gt;Open your work chat app if and only if you receive the notification. Ignore everything else.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While responding to chat messages promptly does give the impression of a diligent engineer, the drawbacks outweigh the benefits. You have disclosed that you are online. It now becomes harder to ignore subsequent messages. Especially when the other person is your boss.&lt;/p&gt;

&lt;p&gt;This situation is best described by Oliver Burkeman in his best-seller &lt;a href="https://www.goodreads.com/book/show/54785515-four-thousand-weeks"&gt;Four Thousand Weeks: Time Management for Mortals&lt;/a&gt;, using email instead, as follow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;you’ll become known as someone who responds promptly to email, so more people will consider it worth their while to message you to begin with&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Tip #4: Ignore non-critical alerts
&lt;/h3&gt;

&lt;p&gt;Critical Alerts refer to ones that require immediate action. Such as a total failure of the company’s only payment system. Others should be counted as non-critical.&lt;/p&gt;

&lt;p&gt;Similarly to Tip #3, we do 3 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setup an Alert Sink. A place to where all Critical Alerts will be sent. If your company is using chat apps like Slack, the Sink is a dedicated channel receiving those alerts.&lt;/li&gt;
&lt;li&gt;Setup notification for Alert Sink. Make sure the notification can reach your phone timely. Additionally, allow it to get your attention by assigning a special ringtone for example.&lt;/li&gt;
&lt;li&gt;Check work chat messages if and only if you receive the notification. Ignore everything else.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If a message doesn’t require immediate action, then it’s only makes sense to address it later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7F5GWq8d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A5YMCN6dSNhohTWRi" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7F5GWq8d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A5YMCN6dSNhohTWRi" alt="A colorful painting of a man lying on the beach surprised when looking at his phone, his hand is holding a cup of mango juice, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip #5: The weekends are for you
&lt;/h3&gt;

&lt;p&gt;Seriously, there are only 7 days in a week, and our work already consumes 5. That is 70%, a tremendous imbalance.&lt;/p&gt;

&lt;p&gt;If week days are money, we are effectively giving 7 out of 10 coins we have to the company and only 3 coins to our loved ones. Worse, this exchange repeats for decades.&lt;/p&gt;

&lt;p&gt;Of course, work is necessary. What I’m trying to say is you really should give the little 30% remaining days to other important aspects in your life. Otherwise, the existing imbalance will only worsen.&lt;/p&gt;

&lt;p&gt;Doing this may put you 2 days behind, but if that task at hand is not urgent, then it really doesn’t matter in the end.&lt;/p&gt;

&lt;p&gt;Work is infinite and our effort is finite, none of us are going to reach the end of “work”. So to go far, I vote for producing consistent and quality work over the long term. It’s a sustainable approach that allows us engineers to stay sane and live our lives to the fullest.&lt;/p&gt;

&lt;p&gt;This perspective does not belong only to myself. It is directly or indirectly suggested by distinguished individuals worldwide.&lt;/p&gt;

&lt;p&gt;In the book &lt;a href="https://www.goodreads.com/book/show/197773418-slow-productivity"&gt;Slow Productivity: The Lost Art of Accomplishment Without Burnout by Cal Newport&lt;/a&gt;, the author argues that Slow Productivity is a sustainable and meaningful approach for knowledge workers. It contains these principles:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Do fewer things.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work at a natural pace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Obsess over quality.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or in &lt;a href="https://www.goodreads.com/book/show/4855.How_to_Live_on_24_Hours_a_Day"&gt;How to Live on 24 Hours a Day by Arnold Bennett&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If a man makes two-thirds of his existence subservient to one-third, for which admittedly he has no absolutely feverish zest, how can he hope to live fully and completely? He cannot.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similarly, in &lt;a href="https://www.goodreads.com/book/show/54785515-four-thousand-weeks?ref=nav_sb_ss_1_11"&gt;Four Thousand Weeks: Time Management for Mortals by Oliver Burkeman&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Rendering yourself more efficient — either by implementing various productivity techniques or by driving yourself harder — won’t generally result in the feeling of having “enough time,” because, all else being equal, the demands will increase to offset any benefits. Far from getting things done, you’ll be creating new things to do.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And finally, these wise words told by a legend:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Remember that careers and jobs are long-term things. Too many young people think they can optimize something and they find they’ve spent couple of years or more specializing something that may not have been the right thing and in the process, they burn out. Because they haven’t spent enough time building up friendships and having a life outside computing.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;~ from an &lt;a href="https://youtu.be/-QxI-RP6-HM?si=iQdCMO0eAk7TiXSh"&gt;interview&lt;/a&gt; with Bjarne Stroustrup, the creator of C++.&lt;/p&gt;

&lt;p&gt;Responsibility to our work is important, yes. But don’t forget that we are also responsible for our bodies and minds, our families, and our friends.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dRp_bRCR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AlX34_6MXdEpHCPLN" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dRp_bRCR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AlX34_6MXdEpHCPLN" alt="A colorful painting of happy men, relaxing on the beach, drinking mango juice, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope that the tips above will help you secure your precious weekends successfully. In fact, I know you will succeed. I have tried and seen it.&lt;/p&gt;

&lt;p&gt;If you have more tips, let us know in the comments. Let’s meet again on a future post.&lt;/p&gt;




</description>
      <category>worklifebalance</category>
      <category>softwareengineerlife</category>
      <category>projectmanagement</category>
      <category>timemanagement</category>
    </item>
    <item>
      <title>Design Pattern: Facade</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Mon, 04 Mar 2024 15:03:46 +0000</pubDate>
      <link>https://dev.to/prestonp/design-pattern-facade-2m44</link>
      <guid>https://dev.to/prestonp/design-pattern-facade-2m44</guid>
      <description>&lt;p&gt;The “Facade” concept focuses on decomposing a complex system into manageable sub-systems, each having its dedicated representative object also called “Facade”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nYQDGEC2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2Au-BDFKcbm7ucqs20AjS95g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nYQDGEC2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2Au-BDFKcbm7ucqs20AjS95g.jpeg" alt="A colorful painting of a collage of 3 images, first is a bottle of mango juice, second is an image of mango farm, third is an image of mango farmers, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The pattern bears a resemblance to micro-service models often employed in large-scale web backend systems, where each micro-service's API serves as a representative.&lt;/p&gt;

&lt;p&gt;Another usage is to let Facade plays the role of an interface with multiple implementations, symbolizing various sub-systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplifying Complexity:&lt;/strong&gt; create a straightforward interface, making it easier for external entities to interact with complex underlying code. The Facade should be designed to be versatile enough for most common requirements. However, direct access to the code behind the Facade is still possible in rare cases where it is truly necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managing Dependent Types:&lt;/strong&gt; When various types are intricately dependent, rearranging them to go through the Facade can streamline dependencies. Instead of relying on N types, one can depend solely on the Facade.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Structure
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mV6K62Jj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/558/0%2Ax3kiI_mUHmf-dG2o" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mV6K62Jj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/558/0%2Ax3kiI_mUHmf-dG2o" alt="" width="558" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Sample Code
&lt;/h4&gt;

&lt;p&gt;An example Facade interface can be written as follows in Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type StockManager struct {
    readyStocks []ReadyStock
    hotStocks []HotStock
}

func (s *StockManager) GetStock(item Item) int {
    stock1 := findReadyStockOfItem(item, readyStocks)
    stock2 := findHotStockOfItem(item, hotStocks)
    return stock1 + stock2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The remaining code for sub-systems is omitted. We can still understand the pattern without it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;Given that this pattern primarily focuses on structuring types, testing is typically not required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Patterns
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Singleton
&lt;/h4&gt;

&lt;p&gt;Often, only one Facade is needed. So we can apply the Singleton pattern ensures this uniqueness.&lt;/p&gt;

&lt;h4&gt;
  
  
  Abstract Factory
&lt;/h4&gt;

&lt;p&gt;Since each sub-system contains inter-related objects, the Abstract Factory pattern can assist in their initialization.&lt;/p&gt;




</description>
      <category>go</category>
      <category>programming</category>
      <category>codinginterviews</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Pair Programming in enterprise</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Thu, 22 Feb 2024 10:10:14 +0000</pubDate>
      <link>https://dev.to/prestonp/pair-programming-in-enterprise-44kh</link>
      <guid>https://dev.to/prestonp/pair-programming-in-enterprise-44kh</guid>
      <description>&lt;p&gt;In the vast landscape of software development methodologies, one timeless technique has stood the test of time — Pair Programming. Many teams avoid this technique due to unfamiliarity and the upfront cost required. Indeed, it’s hard to justify doubling the resource, going from 1 engineer doing 1 task to requiring 2 engineers to do 1 task, not just once, but every week continuously.&lt;/p&gt;

&lt;p&gt;So, how did it go in a real workplace? Let me tell you my experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TbyPdnJ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AbmdEG8lsVyPAT0Tg-Aec6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TbyPdnJ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AbmdEG8lsVyPAT0Tg-Aec6g.png" alt="" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Abyss of Team Dysfunction
&lt;/h3&gt;

&lt;p&gt;I’m in a team of 6 engineers. My teammates are all very smart people and are each familiar with a system they frequently work on. After joining the team, I also get familiar with another system. As time goes by, we do more and more tasks that change our systems, and we don’t really care about the other ones.&lt;/p&gt;

&lt;p&gt;Almost a year passed, and I realized that we have a challenge. A disconnection among teammates hindered effective collaboration, making it difficult for team members to back each other up. Project timelines have to extend more and more frequently due to the siloed approach where each member handles only their familiar system. The growing complexity, intensified by the constant influx of new features, led to stress, a lot of stress.&lt;/p&gt;

&lt;p&gt;We used to have a culture of doing talks. A talk is basically a 30-minute to 1-hour meeting organized by a team member to share anything they want. Mostly, people share about technical problems and solutions at work, or even at their school in the past. I think we learned a lot from each other this way, but that is long gone now. We don’t have time to do talks anymore. Even worse, we can’t even onboard new members properly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In short, the team cannot “scale” further, and it’s time to take action.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Our Beacon: Pair Programming
&lt;/h3&gt;

&lt;p&gt;Although costly to start, research has shown that Pair Programming is a practical and beneficial solution in the long run. The study &lt;em&gt;“On the Economic Feasibility of Pair Programming”&lt;/em&gt; shows an approximate &lt;strong&gt;15%&lt;/strong&gt; longer development time but highlights the subsequent benefits in terms of higher code quality, better design, and lower bug counts.&lt;/p&gt;

&lt;p&gt;Additionally, Cal Newport’s exploration in his book &lt;em&gt;“Deep Work: Rules for Focused Success in a Distracted World”&lt;/em&gt; emphasizes the unparalleled results that stem from intense focus, which he calls Deep Work. Pair Programming inherently fosters focus much like a deep work session.&lt;/p&gt;

&lt;p&gt;Why is that so? Because it shields both programmers from &lt;strong&gt;distractions&lt;/strong&gt; and &lt;strong&gt;procrastination&lt;/strong&gt;. In my opinion, this is the key motivation.&lt;/p&gt;

&lt;p&gt;Armed with research insights, our team decided to venture into the realm of Pair Programming. We scheduled Pair Programming sessions at least once a week. The pairing changes after each week, so each engineer has the chance to work with as many teammates as possible. Simultaneously, a dashboard was deployed to anonymously monitor the bug resolution time of team members, providing a tangible metric to track progress.&lt;/p&gt;

&lt;h3&gt;
  
  
  Emergence from the Depths
&lt;/h3&gt;

&lt;p&gt;As the weeks unfolded, the dashboard unveiled a promising transformation. Bug resolution time gradually decreases, pointing towards the positive impact of Pair Programming on code quality and problem-solving efficiency. The collaborative sessions not only improved the technical aspects but also forged stronger relationships among team members.&lt;/p&gt;

&lt;p&gt;The most surprising result is that it actually decreases our development time! This is because each engineer brings different skills and knowledge into the session. So when Tom doesn’t know where to find the logs, Jerry can jump in to help because he knows it. As a bonus, members began to confidently take on tasks of other systems, breaking down the silos that had plagued the team for so long.&lt;/p&gt;

&lt;p&gt;After three months of Pair Programming, the results spoke for themselves. We are happy with the success and decided to continue the Pair Programming sessions until now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I6irCP3e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AxcFvTzohcP9-V1_ggosFbA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I6irCP3e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AxcFvTzohcP9-V1_ggosFbA.png" alt="" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, our journey through the abyss of team dysfunction to the summit of collaborative success strengthens the result of research studies. Pair Programming, an age-old technique, proved to be the beacon guiding our team out of the abyss, offering a practical solution that not only improves code quality but also cultivates a positive and efficient working environment.&lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://collaboration.csc.ncsu.edu/laurie/Papers/EDSER02WilliamsErdogmus.pdf"&gt;“On the Economic Feasibility of Pair Programming”, Laurie Williams and Hakan Erdogmus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.researchgate.net/publication/2333697_The_Costs_and_Benefits_of_Pair_Programming"&gt;“The costs and benefits of pair programming”, Alistair Cockburn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Deep-Work-Focused-Success-Distracted/dp/1455586692"&gt;“Deep Work: Rules for Focused Success in a Distracted World”, Newport, Cal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>officework</category>
      <category>softwaredevelopment</category>
      <category>teamwork</category>
      <category>pairprogramming</category>
    </item>
    <item>
      <title>Design Pattern: Composite</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Mon, 19 Feb 2024 01:27:51 +0000</pubDate>
      <link>https://dev.to/prestonp/design-pattern-composite-143l</link>
      <guid>https://dev.to/prestonp/design-pattern-composite-143l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--71ZScb0q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AbJF-8sqTEMlKyrIN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--71ZScb0q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AbJF-8sqTEMlKyrIN.png" alt="A colorful painting of a gift box of mangos, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can consider a single type or a composition of related types to be the same by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a new type, usually an interface, to represent them, called &lt;strong&gt;Component&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Allowing recursive structure, meaning Component can contain other child Components. Components within this structure are called &lt;strong&gt;Composite&lt;/strong&gt; , while those without any children are called  &lt;strong&gt;Leaf&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to Use
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When representing hierarchical systems.&lt;/li&gt;
&lt;li&gt;When disregarding the difference between a single object and a composition of objects, treating them all as a Component.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Structure
&lt;/h4&gt;

&lt;p&gt;Let's take the example of a UI framework (something like React). UIComponent represents all types of components such as buttons, text, etc. We also have Popup, which is a more complex component, composed of a button and a text, making it a Composite.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sample Code
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Component&lt;/strong&gt; interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type UIComponent interface {
  Render()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some *&lt;em&gt;Leaf *&lt;/em&gt; types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Text struct{}
func (t *Text) Render() {
  fmt.Print("hello")
}

type Button struct{}
func (b *Button) Render() {
  fmt.Print("button: ")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Composite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Popup struct {
  children []UIComponent
}

func (p *Popup) Render() {
  for _, c := range p.children {
    c.Render()
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text := &amp;amp;Text{}
button := &amp;amp;Button{}
popup := &amp;amp;Popup{
  children: []UIComponent{button, text},
}
popup.Render()

// Output:
// button: hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern offers a way to treat individual objects and compositions uniformly, providing a unified way to work with both. Moreover, we can freely switch the types behind UIComponent interface without affecting the users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;This is a pure pattern for building a structure, so I think we can skip this part 😇&lt;/p&gt;

&lt;h3&gt;
  
  
  Related patterns
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Chain Of Responsibility
&lt;/h4&gt;

&lt;p&gt;If we add the parent UIComponent field to UIComponent interface, we can create a usable structure for the &lt;a href="https://mangotree30.substack.com/p/chain-of-responsibility-pattern"&gt;Chain Of Responsibility&lt;/a&gt; pattern. Check out the pattern's article for more details.&lt;/p&gt;

&lt;h4&gt;
  
  
  Iterator
&lt;/h4&gt;

&lt;p&gt;Iterator can be used to iterate through each component in the Composite structure.&lt;/p&gt;

&lt;h4&gt;
  
  
  Visitor
&lt;/h4&gt;

&lt;p&gt;Helps gather the logic of the components in one place instead of being scattered across Composites and Leaves.&lt;/p&gt;

&lt;h4&gt;
  
  
  Decorator
&lt;/h4&gt;

&lt;p&gt;Often used in conjunction with Composite. Check out the Decorator Pattern for more details.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>designpatterningolan</category>
    </item>
    <item>
      <title>Unveiling the Fully Qualified Domain Name of the Internet</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Fri, 16 Feb 2024 15:06:03 +0000</pubDate>
      <link>https://dev.to/prestonp/unveiling-the-fully-qualified-domain-name-of-the-internet-1f76</link>
      <guid>https://dev.to/prestonp/unveiling-the-fully-qualified-domain-name-of-the-internet-1f76</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Yk6S74V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AFZ_lQ9jbI0Fvsa0r.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Yk6S74V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AFZ_lQ9jbI0Fvsa0r.jpeg" alt="" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigating through the expansive Internet can be like finding one’s way through a bustling city, complete with intricate addresses and postal codes. At the heart of this digital address system lies the Fully Qualified Domain Name (FQDN). Comprising the host name, first-level domain name, and top-level domain name, the FQDN establishes a hierarchical framework similar to physical addresses.&lt;/p&gt;

&lt;h4&gt;
  
  
  Structure of a FQDN
&lt;/h4&gt;

&lt;p&gt;The structure of an FQDN follows a specific pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;host_name&amp;gt;.&amp;lt;first_level_domain_name&amp;gt;.&amp;lt;top_level_domain_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This well-defined structure allows easy identification and classification of web resources, analogous to how physical addresses are organized.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Intention
&lt;/h4&gt;

&lt;p&gt;The intentional design of the FQDN structure aims to bring order and logic to web resource naming and organization. By hierarchically segmenting the domain names, the FQDN enables efficient management and smooth navigation of the digital landscape.&lt;/p&gt;

&lt;h4&gt;
  
  
  An Example: mail.google.com
&lt;/h4&gt;

&lt;p&gt;Taking the example of &lt;strong&gt;“mail.google.com”,&lt;/strong&gt; we can observe the FQDN’s components in action.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“mail” signifies the host name&lt;/li&gt;
&lt;li&gt;“google” represents the first-level domain name&lt;/li&gt;
&lt;li&gt;and “com” indicates the top-level domain&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>internet</category>
    </item>
    <item>
      <title>Design Pattern: Chain Of Responsibility</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Fri, 16 Feb 2024 15:05:48 +0000</pubDate>
      <link>https://dev.to/prestonp/design-pattern-chain-of-responsibility-47g</link>
      <guid>https://dev.to/prestonp/design-pattern-chain-of-responsibility-47g</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DT1cDdxE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AX5km_N9lnLiBzQ7-.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DT1cDdxE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AX5km_N9lnLiBzQ7-.jpeg" alt="A colorful painting of a group of mango farmers working in the field, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A feature can have different logics depending on the usage context. We can hide these logics from the user (caller) by placing them behind an interface. In this way, the caller will not know, and does not need to know, which logic is being used. We call the interface &lt;strong&gt;Handler&lt;/strong&gt; , and each specific logic is a &lt;strong&gt;Concrete Handler&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;There is more than one object that can handle the task we need, and we don’t need to know in advance which object will do that.&lt;/li&gt;
&lt;li&gt;When we want to call multiple objects without having to specify them explicitly. The objects can be combined to do a task that can be chosen at run-time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code Structure
&lt;/h4&gt;

&lt;p&gt;I will use an example of the logging feature. In this case, we can log a string to the console if the string is just normal information, or we will send an email if it is an error. In any case, from the client’s side, there is only the Logger interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4gUMnEf8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/486/0%2AUJ7FDNULTKH-hNU4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4gUMnEf8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/486/0%2AUJ7FDNULTKH-hNU4.png" alt="" width="486" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually, we would leave the most general logic, which can be used in the most cases, at the &lt;strong&gt;end of the chain&lt;/strong&gt;. We want the more specific logics to run first because they might end the chain early.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In programming and problem-solving, it’s common to prioritize more specific and potentially terminating conditions before general ones for efficiency. This approach optimizes the process by handling specific cases early, potentially avoids unnecessary processing.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Sample Code
&lt;/h4&gt;

&lt;p&gt;First, we write the Logger interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type LogLevel string

const (
 Info LogLevel = "info"
 Error LogLevel = "error"
)

type Logger interface {
 Log(level LogLevel, text string)
}

func NewLogger() Logger {
 return &amp;amp;EmailLogger{
  next: &amp;amp;ConsoleLogger{},
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next is a Concrete Handler ConsoleLogger. This logger will write to the console and pass on to the next logger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type ConsoleLogger struct {
  next Logger
}

func (l *ConsoleLogger) Log(level LogLevel, text string) {
  fmt.Printf("%s | %s\n", level, text)
  if l.next != nil {
    l.next.Log(level, text)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second Concrete Handler EmailLogger will only be activated when the log level is Error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type EmailLogger struct {
    next Logger
}

func (l *EmailLogger) Log(level LogLevel, text string) {
 if level == Error {
  fmt.Printf("%s | sent alert email to me", level)
 }
 if l.next != nil {
  l.next.Log(level, text)
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logger := NewLogger()
logger.Log(Info, "hello world")
logger.Log(Error, "the world has already ended due to zombies!")

// Output:
// info | hello world
// error | sent alert email to contact@codenghiemtuc.vn
// error | the world has already ended due to zombies!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;We can test each specific logger like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TestConsoleLogger(t *testing.T) {
  logger := &amp;amp;ConsoleLogger{}
  expect := "haha"

  logger.Log(Info, expect)
  // check console output
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we can just test a chain of logger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TestLoggerChain(t *testing.T) {
    logger := NewLogger()
    expect := "haha"
        logger.Log(Error, expect)
         // check console output
         // check email is sent
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Related Patterns
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Composite
&lt;/h4&gt;

&lt;p&gt;The Composite pattern can be applied to create a hierarchical structure with a child Component pointing to a parent Component, forming a chain. In this way, the child can handle requests and forward them to the parent.&lt;/p&gt;




</description>
      <category>softwareengineering</category>
      <category>designpatterningolan</category>
      <category>programming</category>
    </item>
    <item>
      <title>I reinvented the wheel at work and it didn’t go well</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Thu, 15 Feb 2024 05:59:55 +0000</pubDate>
      <link>https://dev.to/prestonp/i-reinvented-the-wheel-at-work-and-it-didnt-go-well-3f3e</link>
      <guid>https://dev.to/prestonp/i-reinvented-the-wheel-at-work-and-it-didnt-go-well-3f3e</guid>
      <description>&lt;p&gt;Dave the Dev is so excited about his new task to build a new technology at work. It will be the coolest and shiniest thing ever created in my career, he thought. It’s hard but Dave managed to pull through and deliver. So what’s wrong then? Well, the tech doesn’t work as expected and Dave realizes later that a correct solution was already built. Oops.&lt;/p&gt;

&lt;p&gt;You can forget about Dave now. That’s exactly what happened to me when I decided to “reinvent” a Distributed Lock.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7GtqQ-sI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2ABmLtrcqhVmSyyNW8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7GtqQ-sI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2ABmLtrcqhVmSyyNW8.png" alt="A colorful painting of a stale and broken bottle of mango juice, in the style of 1800s, pixel art" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s see what this task is about. There are 2 requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mutual Exclusion&lt;/strong&gt; : at any time, maximum 1 server can acquire the lock
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frequency&lt;/strong&gt; : there must be approximately T seconds between 2 consecutive lock acquisitions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lock is used to give access to a block of code that updates our database.&lt;/p&gt;

&lt;p&gt;Coincidentally, by the time I received the task, I just finished reading &lt;a href="https://www.amazon.com/Redis-Action-Josiah-L-Carlson/dp/1617290858/ref=sr_1_1?crid=1N0ZQUPWMNN6T&amp;amp;keywords=redis+cache&amp;amp;qid=1641528837&amp;amp;sprefix=redis+ca%2Caps%2C348&amp;amp;sr=8-1"&gt;“Redis in Action” by Dr. Josiah L Carlson&lt;/a&gt;. The book has a long section instructing how to implement Distributed Locking. I felt like a teenager who just bought his first motorbike and I could not think of anything else other than to be on the road.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By the way, the book is very good. I recommend fellow engineers to read.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Needless to say, I was determined to make it work. After reviewing my knowledge and some quick research, I chose to use Redis because not only it fits the solution that I learned from the book but it is also an available tool to use in my company.&lt;/p&gt;

&lt;p&gt;It made sense.&lt;/p&gt;

&lt;p&gt;Here is my plan, simplified.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I would setup Redis to store the lock and wrote all the necessary logic to ensure that only one server could acquire the lock. This satisfies Requirement 1. Readers can imagine the lock is stored as &lt;em&gt;lock_key=a_unique _value&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;I would also set the expire time of &lt;em&gt;lock_key&lt;/em&gt; to be exactly T seconds. This satisfies Requirement 2. It actually not enough but at least, this is what I thought.&lt;/li&gt;
&lt;li&gt;Additionally, some minor logic would need to be implemented to handle edge cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It seemed like a great plan, so I and the team spent about 2 weeks developing it into our existing backend. The due date came and I was eager to see the results. Little did I know what lies ahead…&lt;/p&gt;

&lt;p&gt;Of course, the result was not what I had hoped for. Yes, only one server was able to acquire the lock, but the frequency was off, very off. My design could only satisfy Requirement 2 in my head, not in real life. It took a total of 3 long weeks to realize that the chosen approach was not delivering the desired outcome.&lt;/p&gt;

&lt;p&gt;We thought of rolling back, fix it, and then re-release. But the change was already out there and rolling it back was not an option since other teams already released their changes based on ours. Even if we can rollback, we could not figure out a fix that won’t lead to other issues. It felt like our design is fundamentally wrong.&lt;/p&gt;

&lt;p&gt;The frustration was real, and I felt like I had fallen into a deep hole, with no clear way out.&lt;/p&gt;

&lt;p&gt;Just when I thought things couldn’t get any worse, it turned out that there was an existing solution that could have saved us all this trouble — &lt;a href="https://etcd.io/"&gt;ETCD&lt;/a&gt;. Had I explored this option earlier, we could have had a correct solution in just &lt;strong&gt;1 week&lt;/strong&gt; instead of the frustrating weeks we have endured. So the better way had been there all this time. Always.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ETCD works in this case because it has a built-in primitive called “compare and swap” to implement Distributed Lock. More details in this document &lt;a href="https://etcd.io/docs/v3.5/learning/why/#using-etcd-for-distributed-coordination"&gt;Using etcd for distributed coordination&lt;/a&gt;. I plan to write about the usage of this soon, hope you will like it!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The project didn’t succeed. I also didn’t succeed technically. But I did grow up a little bit more in my career. Because this whole experience taught me a valuable lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If I am about to reinvent the wheel, think again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are often existing solutions and technologies within reach that can save time, effort, and unnecessary complications. It’s important to take a step back, evaluate all available options, ask colleagues, and consider whether there’s already a suitable tool or system in place that can effectively address the problem at hand.&lt;/p&gt;

&lt;p&gt;If above steps don’t work, give your self a second chance. Forget about the task for a while by using desperate measures like procrastination, take a walk, take a drink, hit the gym, talk to your dog, or cat,…&lt;/p&gt;

&lt;p&gt;This lesson has now become a guiding principle for me in all future endeavors, and I hope that sharing this experience can help readers avoid similar pitfalls.&lt;/p&gt;




</description>
      <category>distributedsystemdes</category>
    </item>
    <item>
      <title>Simple Hash Map with Scala in 15 minutes</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Fri, 27 Dec 2019 08:04:22 +0000</pubDate>
      <link>https://dev.to/prestonp/simple-hash-map-with-scala-in-15-minutes-4jch</link>
      <guid>https://dev.to/prestonp/simple-hash-map-with-scala-in-15-minutes-4jch</guid>
      <description>&lt;p&gt;Implementing a &lt;a href="https://en.wikipedia.org/wiki/Hash_table"&gt;Hash Map&lt;/a&gt; is a good way to get familiar with a new language, let's see how it can be done quickly in Scala. This article assumes that you are familiar with the data structure. If not, Hacker Earth has a really &lt;a href="https://www.hackerearth.com/practice/data-structures/hash-tables/basics-of-hash-tables/tutorial/"&gt;nice article&lt;/a&gt; to get you started.&lt;/p&gt;

&lt;p&gt;Now, for this implementation, there are a few things I want to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;a href="https://en.wikipedia.org/wiki/Hash_table#Separate_chaining"&gt;chaining&lt;/a&gt; to resolve collisions&lt;/li&gt;
&lt;li&gt;support 3 operations: &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, and &lt;code&gt;get&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;immutability (all modifications return a new map instead of changing the existing one) (&lt;a href="https://stackoverflow.com/a/34385684/3778765"&gt;but why?&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With those requirements in mind, let's write a short outline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Entry&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;private&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Entry&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]]])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;???&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Class &lt;code&gt;Entry&lt;/code&gt; represents a key-value pair&lt;/li&gt;
&lt;li&gt;I use &lt;code&gt;Vector&lt;/code&gt; to hold the keys. Each key contains another &lt;code&gt;Vector&lt;/code&gt; that holds all the values. Hence we have &lt;code&gt;Vector[Vector[Entry[K, V]]]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Since my hash map is immutable, &lt;code&gt;add&lt;/code&gt; must return a new hash map. The original map is left untouched.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get&lt;/code&gt; returns an &lt;code&gt;Option&lt;/code&gt; that contains the value of that key if it exists and &lt;code&gt;None&lt;/code&gt; otherwise&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;???&lt;/code&gt; means &lt;code&gt;throw new NotImplementedException()&lt;/code&gt;, which is quite convenient for writing code outline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Method &lt;code&gt;add&lt;/code&gt; is quite straight forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;idx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;indexFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// if the table is empty, initialize and then run 'add' again&lt;/span&gt;
  &lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;init&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// otherwise, if 'key' exists, replace its old value&lt;/span&gt;
  &lt;span class="c1"&gt;// if not, associate 'value' with 'key'&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;chain&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;indexWhere&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// key not found&lt;/span&gt;
        &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;e&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Entry&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;+:&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;replaced&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;chain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replaced&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;initialCapacity&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Vector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialCapacity&lt;/span&gt;&lt;span class="o"&gt;)(&lt;/span&gt;&lt;span class="nv"&gt;Vector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/** Returns the index of this key in the internal entry vector. */&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;indexFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;length&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;remove&lt;/code&gt; is a bit tricky to write since we cannot do an 'in-place' removal (ahem, immutability ...). So we have to use &lt;code&gt;filter&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;K&lt;/span&gt;, &lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;idx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;indexFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;updated&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;key&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this is not the most efficient way  because &lt;code&gt;filter&lt;/code&gt; will go through the whole collection instead of stopping once the unwanted element is seen. A more efficient approach to this case is to not remove anything at all but just 'mark' the element as removed. But I will not implement that here 😅&lt;/p&gt;

&lt;p&gt;And lastly, we need to write out &lt;code&gt;get&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;K&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;V&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;idx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;indexFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method &lt;code&gt;find&lt;/code&gt; of &lt;code&gt;Vector&lt;/code&gt; already returns an &lt;code&gt;Option&lt;/code&gt; if there is no element match with &lt;code&gt;key&lt;/code&gt; so we don't need to manually handle that. Utility methods like &lt;code&gt;find&lt;/code&gt; is the reason why I love Scala so much. It allows me to leave work early.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--06HkRkew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/r37uobxukali0her2wdv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--06HkRkew--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/r37uobxukali0her2wdv.png" alt="leave_work" width="258" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! We have completed our Hash Map implementation that satisfied the requirements we made at the beginning. You can use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;map&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;, &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="nv"&gt;Vector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;web&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"web"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1 -&amp;gt; "web"&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;dev&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;web&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"dev"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1 -&amp;gt; "web", 2 -&amp;gt; "dev"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Array&lt;/code&gt; can be used for faster indexed access. Here, I use &lt;code&gt;Vector&lt;/code&gt; to keep everything immutable.&lt;/li&gt;
&lt;li&gt;This implementation uses a constant capacity (and it shouldn't). In practice, you should add some logic in method &lt;code&gt;add&lt;/code&gt; to increase the capacity when needed. This is important to maintain performance.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>scala</category>
      <category>hashmap</category>
    </item>
    <item>
      <title>5 reasons to learn Scala in 2019</title>
      <dc:creator>Preston Pham</dc:creator>
      <pubDate>Fri, 20 Dec 2019 04:35:04 +0000</pubDate>
      <link>https://dev.to/prestonp/5-reasons-to-learn-scala-in-2019-41o2</link>
      <guid>https://dev.to/prestonp/5-reasons-to-learn-scala-in-2019-41o2</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fg960p8ugr45oztlnnvxo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fg960p8ugr45oztlnnvxo.jpg" alt="scala"&gt;&lt;/a&gt;&lt;br&gt;
If you are looking for a new programming language to learn this year, &lt;a href="https://www.scala-lang.org/" rel="noopener noreferrer"&gt;Scala&lt;/a&gt; is a good choice. Here are 5 reasons why:&lt;/p&gt;
&lt;h2&gt;
  
  
  Flexibility
&lt;/h2&gt;

&lt;p&gt;If it is 10 years ago, I would never recommend Scala to anyone. Because a programming language can be very fast, elegant, and feature rich but is still not good to learn if nobody else is using it. However, that is not the case anymore because Scala has been growing quickly and is now used in many areas such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web frontend with &lt;a href="https://www.scala-js.org/" rel="noopener noreferrer"&gt;ScalaJS&lt;/a&gt; and &lt;a href="https://github.com/japgolly/scalajs-react" rel="noopener noreferrer"&gt;ScalaJS React&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Web server with &lt;a href="https://github.com/playframework/playframework" rel="noopener noreferrer"&gt;Play&lt;/a&gt;, &lt;a href="https://github.com/lift/framework" rel="noopener noreferrer"&gt;Lift&lt;/a&gt;, and &lt;a href="https://github.com/akka/akka-http" rel="noopener noreferrer"&gt;Akka HTTP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Android app with &lt;a href="https://github.com/scala-android/sbt-android" rel="noopener noreferrer"&gt;Scala on Android&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Data processing with &lt;a href="https://github.com/apache/spark" rel="noopener noreferrer"&gt;Spark&lt;/a&gt; and &lt;a href="https://github.com/apache/kafka" rel="noopener noreferrer"&gt;Kafka&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is even an &lt;a href="https://github.com/ornicar/lila" rel="noopener noreferrer"&gt;open-source chess server&lt;/a&gt; written in Scala.&lt;/p&gt;
&lt;h2&gt;
  
  
  Elegance
&lt;/h2&gt;

&lt;p&gt;Having used C++, C#, Java, and Python, I can say that Scala has a very concise and expressive syntax.&lt;/p&gt;

&lt;p&gt;For example, to print "hello world" on console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello world"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To declare a value (or variable in Java):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;j&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="c1"&gt;// automatically inferred as `Int`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To declare a method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To remove all odd numbers in a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;isEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// result: List(2)&lt;/span&gt;
&lt;span class="c1"&gt;// or more like English&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt; &lt;span class="c1"&gt;// result: List(2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can omit punctuations to have a more English-like syntax for extra expressiveness, this is called &lt;a href="https://docs.scala-lang.org/style/method-invocation.html" rel="noopener noreferrer"&gt;infix notation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rich API
&lt;/h2&gt;

&lt;p&gt;Scala built-in library comes with an extremely rich API. Filtering a list in the code snippet above is a very typical example.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;List&lt;/code&gt; API also contains many other methods. For example, to loop through each item in a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;foreach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To sum a list of numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="nv"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;sum&lt;/span&gt; &lt;span class="c1"&gt;// result: 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works as long as the list contains numbers (e.g. integers, doubles...)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnoxhw4mwachctuv9p7dc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnoxhw4mwachctuv9p7dc.png" alt="it_just_works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Computing the intersection of 2 lists is also simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;l1&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;l2&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;l1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;intersect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// result: List(2, 3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Great community &amp;amp; libraries
&lt;/h2&gt;

&lt;p&gt;Yes, indeed. Compared to NodeJS or Python, Scala has a much smaller community and far fewer libraries (not counting Java ones). But it is not really bad because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most of the time, we only use a few top libraries and those in Scala have high quality to make up for quantity&lt;/li&gt;
&lt;li&gt;People are very active and willing to help each other. Especially Gitter channels like &lt;a href="https://gitter.im/spark-scala/Lobby" rel="noopener noreferrer"&gt;Spark with Scala&lt;/a&gt; and &lt;a href="https://gitter.im/typelevel/cats" rel="noopener noreferrer"&gt;typelevel/cats&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Java Interoperability
&lt;/h2&gt;

&lt;p&gt;Simply said, &lt;strong&gt;Java methods&lt;/strong&gt; can be called and &lt;strong&gt;Java classes&lt;/strong&gt; can be extended in Scala code. This means you have access to all Java libraries out there.&lt;/p&gt;

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

&lt;p&gt;I was once questioning why should I use a language that looks so complicated. But after I understand Scala and realize how my life becomes much more easier, I'm in love with it. If the 5 reasons above are interesting to you,  make sure to check out &lt;a href="https://docs.scala-lang.org/tour/tour-of-scala.html" rel="noopener noreferrer"&gt;a short tour of Scala&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's my first post to DEV, if you have any question or feedback, please let me know :)&lt;/p&gt;

</description>
      <category>scala</category>
    </item>
  </channel>
</rss>
