<?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: Alex Fedorov</title>
    <description>The latest articles on DEV Community by Alex Fedorov (@waterlink).</description>
    <link>https://dev.to/waterlink</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%2F34456%2Ffc0ad32a-b2cb-4af2-85bb-24281cfc60ca.jpg</url>
      <title>DEV Community: Alex Fedorov</title>
      <link>https://dev.to/waterlink</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/waterlink"/>
    <language>en</language>
    <item>
      <title>When Is the Perfect Time to Move on as a Developer?</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Tue, 11 Feb 2020 16:48:04 +0000</pubDate>
      <link>https://dev.to/foundsiders/when-is-the-perfect-time-to-move-on-as-a-developer-ofb</link>
      <guid>https://dev.to/foundsiders/when-is-the-perfect-time-to-move-on-as-a-developer-ofb</guid>
      <description>&lt;p&gt;&lt;strong&gt;If you want to have a simple, easy, comfy, safe and secure job, then stop reading this post right this moment!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Still here?&lt;/p&gt;

&lt;p&gt;Good. Let’s do this then!&lt;/p&gt;

&lt;h2&gt;
  
  
  20yrs of experience or 1yr repeated 20 times?
&lt;/h2&gt;

&lt;p&gt;If you’ve been a developer for a while, you probably have noticed that there are folks with double-digit experience in years.&lt;/p&gt;

&lt;p&gt;But they are not as good as you wish they were.&lt;/p&gt;

&lt;p&gt;They focus on wrong things, they are stuck in the past way of doing things, and use outdated technology, or want to spend as much as possible of their time in the meeting.&lt;/p&gt;

&lt;p&gt;(so that they don’t have to do actual work).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is a term in the industry for these developers: “1 year of experience repeated N times.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, it’s not so black and white, and you can have somebody who has legit 3-4 years of experience, but then they got stuck in a situation that didn’t really allow them to acquire new skills, and they were repeating these 3-4 years (or subset of them) for a while now.&lt;/p&gt;

&lt;p&gt;So we have a whole range, from people who are plain harmful to the team, product, and the company, &lt;strong&gt;who just want a safe and secure job and do as least work as possible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And somewhere in the middle, we have well-meaning folks who have lost their ability to learn new things, improve, and &lt;strong&gt;are terrified of stepping outside of their comfort zone.&lt;/strong&gt; They may be a good worker or inadvertently block others from improving and delivering value quickly.&lt;/p&gt;

&lt;p&gt;Finally, you have someone who had 20 years of experience, and &lt;strong&gt;this experience was always unique, challenging, and still extending their comfort zone further and further.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are top performers who help each team member around them and deliver exceptional results. And if you ask them tomorrow what they learned yesterday—they’ll always have something interesting to say.&lt;/p&gt;

&lt;p&gt;Unfortunately, it’s way to easy to fall into a trap and get stuck in the middle, or even worse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s way too easy to become “1 year repeated 20 times.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you finish reading this article, you’ll be well-equipped to prevent that from happening and even become exceptional with real 20 years of experience.&lt;/p&gt;

&lt;p&gt;But before we jump into solutions, why not dive deeper into the problem?&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem: wasting experience years
&lt;/h2&gt;

&lt;p&gt;This problem occurs when you are wasting entire years of your experience, just doing a secure, comfy job, where you don’t need to challenge yourself or learn anything (or much).&lt;/p&gt;

&lt;p&gt;One thing is to waste years entirely (sure way to become an epitome of “1 year repeated 20 times”), and another thing is to have the &lt;strong&gt;quality of these years of experience reduced.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What do I mean by reduced?&lt;/p&gt;

&lt;p&gt;That’s when you are still learning a bit, and it’s a bit challenging, but it is way below what you can really handle, and it is not really stretching your comfort zone enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real experience is gained outside of your comfort zone.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How does this happen?&lt;/p&gt;

&lt;p&gt;For example, you may be good enough with the technology at your job, and you can handle 98% of the work with your closed eyes.&lt;/p&gt;

&lt;p&gt;Then the process—it’s just working for you, okay, even though there are definite improvements that can be done to get 50-80% efficiency gains, but no—why touch what works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why risk it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why step outside of your comfort zone, and pull your team with you?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s the line of thinking that gets the person, the team, and the organization into the reduced quality of experience mode.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also, the reduced quality of performance as a long-term result of this all.&lt;/p&gt;

&lt;p&gt;Another problem with such complacency is that &lt;strong&gt;the longer you don’t step out of your comfort zone, the harder it’ll be to do in the future.&lt;/strong&gt; Eventually, it becomes a terrifying step and almost nigh impossible to do.&lt;/p&gt;

&lt;p&gt;Don’t ever let it get to this point!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The right mindset is one of continuous improvement and growth.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this mindset, you’re going to be improving yourself, your team, people around you, product, codebase, and the company you’re in (and maybe even the world) all the time, with small incremental, but definite steps.&lt;/p&gt;

&lt;p&gt;Of course, you’re going to fail.&lt;/p&gt;

&lt;p&gt;And that’s good. &lt;strong&gt;Failures are the signs of learning&lt;/strong&gt;, and of you attempting to do something very likely to be worth it.&lt;/p&gt;

&lt;p&gt;People who don’t fail—do not learn.&lt;/p&gt;

&lt;p&gt;This mindset is how you maximize your own experience quality and get the most out of your time and how you become a top performer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello, dear skeptic
&lt;/h2&gt;

&lt;p&gt;I know what you might be thinking:&lt;/p&gt;

&lt;p&gt;It’s a terrible idea only to do new things, and only learn, because you have to become good at something via repetition and practice, before you can perform at a decent level.&lt;/p&gt;

&lt;p&gt;If that’s what you’re thinking, I cannot agree more with you!&lt;/p&gt;

&lt;p&gt;I don’t advocate limiting yourself to doing new things only.&lt;/p&gt;

&lt;p&gt;Instead, &lt;strong&gt;you should get your existing skills to an excellent level&lt;/strong&gt; until things start to get more comfortable. And that is the right moment to add some more skills or responsibilities to your repertoire.&lt;/p&gt;

&lt;p&gt;This way, you &lt;strong&gt;always maintain a constant cumulative level of challenge while delivering excellent quality work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alright, let’s get technical with how you can keep ever-increasing the quality of your experience years:&lt;/p&gt;

&lt;h2&gt;
  
  
  Practice and get better at what you’re already doing
&lt;/h2&gt;

&lt;p&gt;If you are already doing something well, and it’s quite easy to deliver your work, then it’s time to start challenging yourself.&lt;/p&gt;

&lt;p&gt;How?&lt;/p&gt;

&lt;p&gt;You establish restrictions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try to do it faster&lt;/strong&gt; while keeping the same level of quality;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try to improve quality&lt;/strong&gt;, while spending the same amount of time;&lt;/li&gt;
&lt;li&gt;Help others to do this better—&lt;strong&gt;become multiplier&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In essence, &lt;strong&gt;practice, deliver, fail, get feedback, learn from it, and improve.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every day.&lt;/p&gt;

&lt;p&gt;If you do that, soon you’re going to reach a point where the amount of effort and time it takes to improve is just too much for the increase of effectiveness or quality.&lt;/p&gt;

&lt;p&gt;This is where you can start handling some more responsibilities:&lt;/p&gt;

&lt;h2&gt;
  
  
  Get more responsibilities
&lt;/h2&gt;

&lt;p&gt;For example, you’re getting really good at 2 out of the 3 necessary skills to do your job, and your boss is pleased with both of your current responsibilities.&lt;/p&gt;

&lt;p&gt;Then it’s time to &lt;strong&gt;look around you and see what should be done, but it’s not getting done&lt;/strong&gt;, or not consistently, and no one is responsible for.&lt;/p&gt;

&lt;p&gt;But your gut really tells you these things have to get done consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get the ownership of that. Just start doing that. Learn in the process. Take that responsibility.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, you’ll make mistakes. But you have your saving grace—you’re trying to make things better for everybody around you.&lt;/p&gt;

&lt;p&gt;Once you get 10-20% of the mastery of that responsibility and see some good outcomes, go to your boss and “make it official.”&lt;/p&gt;

&lt;p&gt;If it so happens that there are no responsibilities around you to take ownership of, then you should go with a new skill:&lt;/p&gt;

&lt;h2&gt;
  
  
  Get more skills
&lt;/h2&gt;

&lt;p&gt;For example, you’re handling all responsibilities that suit you, and all of your three skills are at the level where improving them doesn’t make too much sense anymore. They’re that good.&lt;/p&gt;

&lt;p&gt;Then it’s time to &lt;strong&gt;hunt some more skills for your belt.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, look at &lt;strong&gt;what new skills you want to have&lt;/strong&gt; (try to guess what you may need in the future), or what you think you’ll love to do.&lt;/p&gt;

&lt;p&gt;Second, take a &lt;strong&gt;look at your environment, what skills are lacking in it?&lt;/strong&gt; That’ll be beneficial to either the team, product, or company as a whole.&lt;/p&gt;

&lt;p&gt;Now, &lt;strong&gt;intersect the two. What’s left is what you should be learning&lt;/strong&gt;, practicing, and start applying at your job.&lt;/p&gt;

&lt;p&gt;Again, &lt;strong&gt;practice, deliver, fail, get feedback, improve, and repeat.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, there is a dark side to all of that. Let’s chat about it:&lt;/p&gt;

&lt;h2&gt;
  
  
  What you SHOULD NOT do
&lt;/h2&gt;

&lt;p&gt;If you realize that what you want to learn doesn’t fit your current company or role, then &lt;strong&gt;forcing it into your job will bring a lot of harm&lt;/strong&gt; to the people around you, product, and your company.&lt;/p&gt;

&lt;p&gt;An excellent example of that’d be a new fancy programming language or technology. But you have to come up with almost implausible excuses to use it at your job.&lt;/p&gt;

&lt;p&gt;My personal work ethics tells me that this is a horrible idea then.&lt;/p&gt;

&lt;p&gt;Therefore, this is not something you want to do.&lt;/p&gt;

&lt;p&gt;Don’t be too selfish.&lt;/p&gt;

&lt;p&gt;But what &lt;strong&gt;if you see this skill or that responsibility as a vital component of your future career?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, if you really think so, then there is a solution for you:&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s time to move on
&lt;/h2&gt;

&lt;p&gt;For instance, you are in the unfortunate situation where &lt;strong&gt;what you want to get better at, doesn’t benefit your employer or your team (or even harms them).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then it’s time to start searching for a new job&lt;/strong&gt;, and if your company is big enough, &lt;strong&gt;investigate what other roles/departments you can move in&lt;/strong&gt;, where it’d work well.&lt;/p&gt;

&lt;p&gt;Your goal is to start learning and practicing it on your own (and in 10% time if you have that benefit at your company), but &lt;strong&gt;not force it into your day-to-day work (to do no harm).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In parallel, &lt;strong&gt;talk to people.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A lot of them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learn what companies are out there, and who may need your current skillset plus what you’re trying to learn.&lt;/p&gt;

&lt;p&gt;Reach out to them and try to get through the interview process. You probably will have to play a number game, because, while you’re expert in a few topics, you’re still learning this one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Look for something that will fit your chosen direction as best as possible&lt;/strong&gt;, and where you, learning this on the job, will be precious to the team and a company as well.&lt;/p&gt;

&lt;p&gt;I cannot stress enough—&lt;strong&gt;it’s going to be challenging.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And it’s well worth it!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also, since you are changing roles/companies, it’s an excellent opportunity &lt;strong&gt;to negotiate a higher paycheck&lt;/strong&gt;. For example, &lt;strong&gt;with this website for developers you can share your salary info and &lt;a href="https://fellowage.io/?r=dt"&gt;find out how much people earn at the other company&lt;/a&gt; you are negotiating with.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, depending on your aspirations and goals for the future, it may be a good idea to start your own thing:&lt;/p&gt;

&lt;h2&gt;
  
  
  Go independent
&lt;/h2&gt;

&lt;p&gt;If your &lt;strong&gt;ambitions cannot be satisfied anymore&lt;/strong&gt; by any organization around you (or even remotely, in a different country), then you’re likely to be &lt;strong&gt;ripe to go independent.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What do I mean by that?&lt;/p&gt;

&lt;p&gt;Well, there are three options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;become a freelancer,&lt;/li&gt;
&lt;li&gt;start your own product company,&lt;/li&gt;
&lt;li&gt;start a service company or agency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is, of course, a whole lot to learn there. And a lot of potential failures to encounter.&lt;/p&gt;

&lt;p&gt;And that’s good. As we established, &lt;strong&gt;this increases the quality of your years of experience!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are trade-offs to these options, and probably more I haven’t thought about yet. I’m not going to cover these in this post—it’s already getting long! (sorry about that)&lt;/p&gt;

&lt;p&gt;What I should tell you, is that there are &lt;strong&gt;few things you should do before going independent:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure to &lt;strong&gt;save some money for N months&lt;/strong&gt;—you need that runway because success won’t come on day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Line up a job or contractor opportunity in N months&lt;/strong&gt; for the worst-case scenario where you have failed a lot of times and never succeeded getting anything off the ground.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just remember, &lt;strong&gt;failing is not a bad thing.&lt;/strong&gt; If you are failing and failing often—that’s great. (Just don’t forget to learn and improve between failures).&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;much worse if you are not failing for a long while&lt;/strong&gt;, only to run out of all your saved money and realize that the whole venture was one big failure, and you haven’t had an opportunity to learn from it. And now it’s too late.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get a mentor. Almost every successful independent person had a mentor&lt;/strong&gt;. That’s one of the primary ways you’re going to get feedback on what you do and improve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seek external feedback as often as you can&lt;/strong&gt;. Sometimes, in business, what appears to be a failure to you, may actually be a bud of the enormous success that you can’t see because you lack a specific type of experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;That’s the hardest path, and it’s well worth the effort.&lt;/strong&gt; Good luck, and let’s summarize:&lt;/p&gt;

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

&lt;p&gt;As you know, some folks have 20 years of experience, but actually, just one year repeated 20 times. Let’s call it “the left side” of the scale.&lt;/p&gt;

&lt;p&gt;And then there are outstanding professionals, who have only, what 7 years, but all of these years are unique experiences that make them exponentially better than the former. These are probably top performers in their field. Let’s call it “the right side” of the scale.&lt;/p&gt;

&lt;p&gt;(pun intended)&lt;/p&gt;

&lt;p&gt;And then there is everything in between.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how does one get closer to the right side?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Don’t chase only “new and unique” all the time—make sure you actually &lt;strong&gt;get good at skills and responsibilities before you add more things to your repertoire.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge yourself every day.&lt;/strong&gt; Be ready to answer the question “what did you learn yesterday” with something substantial. Perhaps add “how did you fail last week” to the list of these must-be-able-to-answer questions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In fact, answer these questions every day, if you can help it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never become complacent and have an “easy job.”&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get more skills&lt;/strong&gt; that’ll help your team/product/company to become more successful when your current skillset starts to near the “easy job” state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Become responsible for more&lt;/strong&gt; (and more important/challenging) things.&lt;/li&gt;
&lt;li&gt;Make sure that what you’re adding to your “toolbelt” &lt;strong&gt;is actually valuable to people around you, your product, your company, or your customers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If your path forward makes the above not true, then it’s time to switch a job. &lt;strong&gt;Don’t forget to negotiate a larger paycheck, as this is the easiest time to do that! &lt;a href="https://fellowage.io/?r=dt"&gt;Use this to find out what is the pay at the company you are negotiating with&lt;/a&gt;.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Finally, if such a company doesn’t exist (or is inaccessible to you)—then &lt;strong&gt;create one! Become independent.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Now it’s your turn!
&lt;/h2&gt;

&lt;p&gt;Quality of the years of your experience is entirely in your hands. Don’t let weak excuses make you think that somebody else is responsible for your career.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are the only one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And &lt;strong&gt;you owe yourself&lt;/strong&gt; to get as close as you can to “the right side” of this experience scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So get out there, and never ever stop learning!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@joshstyle" rel="noopener nofollow noreferrer"&gt;Joshua Coleman&lt;/a&gt; from &lt;a href="https://unsplash.com" rel="noopener nofollow noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How have I ensured the privacy and anonymity of my website users? 🤔</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Tue, 17 Dec 2019 00:14:15 +0000</pubDate>
      <link>https://dev.to/foundsiders/how-have-i-ensured-the-privacy-and-anonymity-of-my-website-users-5fgb</link>
      <guid>https://dev.to/foundsiders/how-have-i-ensured-the-privacy-and-anonymity-of-my-website-users-5fgb</guid>
      <description>&lt;p&gt;Over the course of the past month, I’ve built the first version of &lt;a href="https://www.producthunt.com/posts/fellowage"&gt;FelloWage&lt;/a&gt;—a website that allows users to share their salary information and view information shared by others.&lt;/p&gt;

&lt;p&gt;Of course, I wanted to keep the information of my users private and anonymous. When somebody is looking at the wage entry, they shouldn’t be able to tell who this entry belongs to.&lt;/p&gt;

&lt;p&gt;On the other hand, to keep the quality of the shared data high, users should be able to update their salary entries when they change over time. Thus the wage records need to be somehow connected to the respective user accounts.&lt;/p&gt;

&lt;p&gt;This poses an issue: if I implement it in the most obvious way (a database foreign key relation), then the website operator (me), effectively, has access to this connection between the user account and a salary record. Also, legal authorities coming with a court order will be able to see this as well, and in the unfortunate case of a successful cyber attack, the hackers will get their hands on this data too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nDEoMIkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kq4e9lsc7vm2ucj6phcq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nDEoMIkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kq4e9lsc7vm2ucj6phcq.jpg" alt="Privacy problem" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not good enough! How can we do better?
&lt;/h2&gt;

&lt;p&gt;We are looking for a solution where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the wage entry is readable by all users of the system,&lt;/li&gt;
&lt;li&gt;the connection between wage entry and the user account is readable &lt;strong&gt;ONLY&lt;/strong&gt; by the user account owning that entry,&lt;/li&gt;
&lt;li&gt;user accounts are readable to the system (at least partially) for the purposes of the login system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my scenario, since the user sign-up verification is a manual process, I needed the system to be able to write this connection without the presence of the user.&lt;/p&gt;

&lt;p&gt;If we sum it up: only the user should be able to read a connection record, and the system should be able to write this record (but not read it).&lt;/p&gt;

&lt;h2&gt;
  
  
  Assymetric encryption
&lt;/h2&gt;

&lt;p&gt;This sounds to me like asymmetric encryption, where the system knows the user’s public key, and the user knows their own private key. The system uses the public key to encrypt the information when it needs to write it, and the user can read that information using their private key.&lt;/p&gt;

&lt;p&gt;Of course, the next challenge is UX. We can’t have the users use private keys every time they want to login.&lt;/p&gt;

&lt;p&gt;That’d be too clunky.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TND1BClF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4bf3r4vvrr144py8pdtx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TND1BClF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4bf3r4vvrr144py8pdtx.png" alt="Asymmetric encryption" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Passphrase-encrypted private key
&lt;/h2&gt;

&lt;p&gt;Then it has stricken me: what if I do the same thing SSH keys do when you set them up with a passphrase?&lt;/p&gt;

&lt;p&gt;Now the system will store both types of keys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the public key, and&lt;/li&gt;
&lt;li&gt;the private key encrypted using the user’s password.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, even if I were to drop into the raw SQL in my database console, I wouldn’t be able to tell who owns which wage entries anymore! And the user can still see and manage their own entry.&lt;/p&gt;

&lt;p&gt;As a bonus, I’ve found this method of securing the user’s data quite convenient, and I used it for other information as well, where I’m sure that only the user will need access to this data.&lt;/p&gt;

&lt;p&gt;Of course, we still need to make sure that the users create strong passwords that are not vulnerable to dictionary attacks, and weren’t part of any breach. I’ve used &lt;a href="https://github.com/dropbox/zxcvbn"&gt;zxcvn by Dropbox&lt;/a&gt; library and &lt;a href="https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange"&gt;“Have I Been Pwned” API&lt;/a&gt; for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for reading!
&lt;/h2&gt;

&lt;p&gt;I’m glad you’ve gotten to the end of this post! If you are interested in more behind-the-scenes posts like this, you should subscribe to our newsletter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The next post that is in the making is a deeper dive into the implementation details and challenges of the solution from this article. Don’t miss it, &lt;a href="https://foundsiders.typeform.com/to/ym5OHB"&gt;grab our newsletter here&lt;/a&gt;! 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thank you for your support!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>showdev</category>
      <category>security</category>
    </item>
    <item>
      <title>How Can Hierarchical Test Structure Absolutely Make a Mess?</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Sat, 02 Mar 2019 14:41:05 +0000</pubDate>
      <link>https://dev.to/waterlink/how-can-hierarchical-test-structure-absolutely-make-a-mess-27fb</link>
      <guid>https://dev.to/waterlink/how-can-hierarchical-test-structure-absolutely-make-a-mess-27fb</guid>
      <description>&lt;p&gt;Have you ever written your unit tests using a simple xUnit style testing framework?&lt;/p&gt;

&lt;p&gt;Then you probably know, as tests get more complex, the more boilerplate and duplication they collect, either spread among the test methods, or setup functions.&lt;/p&gt;

&lt;p&gt;Now, hierarchical context frameworks are pretty robust to mitigate this boilerplate problem and remove this duplication. They allow you to have nested contexts each one having their own little bit of setup, and “inheriting” the setup of parent contexts.&lt;/p&gt;

&lt;p&gt;This way, you can express lots of different scenarios without actually repeating yourself even once in the test setup code.&lt;/p&gt;

&lt;p&gt;Great, isn’t it?&lt;/p&gt;

&lt;p&gt;Now, what if I told you that hierarchical test structure can cause more subtle duplication (that it was supposed to prevent in the first place) that is hard to spot and refactor?&lt;/p&gt;

&lt;p&gt;Let me give you an oversimplified example:&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Fetchers, elusively alike
&lt;/h2&gt;

&lt;p&gt;The other day, I was working on two “fetcher” classes that talk to the HTTP client for 3rd party API and contain business logic of what needs to be done, and also can handle both immediate “successful,” and asynchronous “accepted” responses.&lt;/p&gt;

&lt;p&gt;Their code was pretty similar, and whole logic of handling the response, and re-scheduling the async task was duplicated, so we have refactored it in a separate collaborator object in the production code.&lt;/p&gt;

&lt;p&gt;Then we thought: “Well, we refactored duplication in the production code. There bound to be a duplication in the test code. Let’s get it DRYed as well!”&lt;/p&gt;

&lt;p&gt;Not so fast!&lt;/p&gt;

&lt;p&gt;When we started reading two test suites side-by-side, it turned out that they don’t look too much alike. It was hard to spot and isolate the duplication.&lt;/p&gt;

&lt;p&gt;They were written in a hierarchical style, and they were leveraging the full power of nested contexts.&lt;/p&gt;

&lt;p&gt;Here is a reduced example for the first test (in Kotlin):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FetcherOne"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AsyncQueue&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FetcherOne&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withMockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// … more irrelevant variables here …&lt;/span&gt;

    &lt;span class="nf"&gt;beforeEachTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;asyncQueue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AsyncQueue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;fetcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetcherOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"perform"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;beforeEachTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tells client to do stuff"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"doStuff"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"triggers an async polling job"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;pollStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// … more irrelevant tests here …&lt;/span&gt;

        &lt;span class="nf"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"when there is no need to check for status"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;beforeGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"does not trigger an async polling job"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// … more irrelevant tests here …&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// … more irrelevant contexts here …&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the test suite starts with the root context. Here is where you can set the global defaults for your test suite, and override some of them in the nested contexts.&lt;/p&gt;

&lt;p&gt;This is good if you have a typical “happy path” scenario, and then you have more “special cases,” for which you’ll use nested contexts.&lt;/p&gt;

&lt;p&gt;Notice that we’re mocking the HTTP client to respond with an “accepted” status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withMockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then in one of the nested contexts, we override the response status to “successful”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;beforeGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that all in mind, take a look at the second test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FetcherTwo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AsyncQueue&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FetcherTwo&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// … more irrelevant variables here …&lt;/span&gt;

    &lt;span class="nf"&gt;beforeGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;beforeEachTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;asyncQueue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AsyncQueue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;fetcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetcherTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"perform"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;beforeEachTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tells client to do some other stuff"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"doSomeOtherStuff"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"does not trigger an async polling job"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// … more irrelevant tests here …&lt;/span&gt;

        &lt;span class="nf"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"when there is a need to check operation status async"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;beforeGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"triggers an async job to check the last operation"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;checkLastOperation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// … more irrelevant tests here …&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// … more irrelevant contexts here …&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the author of this test suite have chosen a different response status as the default “happy-path” scenario—“successful”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;beforeGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(and used a different mocking style on top of that)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And the nested context overrides the response status to “accepted” status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;beforeGroup&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, with this example, you could figure out how to refactor it quickly enough, after inverting the default and custom scenarios for one of the test suites, right?&lt;/p&gt;

&lt;p&gt;This example is elementary. What we had was more complicated. Imagine that your async polling and retrying logic (what we were trying to refactor) was dependent on 4 factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’ll have 4 levels of nested contexts describing each element as a part of the overall scenario;&lt;/li&gt;
&lt;li&gt;Each context may choose a different default case as opposed to which ones should be overridden in the inner context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, this can quickly become a mess, and very hard to refactor.&lt;/p&gt;

&lt;p&gt;If we had a classic flat test structure, we’d have a little bit of duplication in the test suite, but it would be so much easier to compare test suites side-by-side and refactor them.&lt;/p&gt;

&lt;p&gt;Let me show you an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FetcherOne"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AsyncQueue&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FetcherOne&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;beforeEachTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;asyncQueue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AsyncQueue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;fetcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetcherOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"perform - calls client"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"doStuff"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"perform - triggers async polling job when accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"accepted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;pollStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"perform - does not trigger async job when successful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockResponseStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"successful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;fetcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asyncQueue&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second test suite will now look very similar (not worth showing here, but you &lt;a href="https://gist.github.com/waterlink/e26a4dc585b628d6eb6074b9383a209f"&gt;can see the gist&lt;/a&gt; if you like).&lt;/p&gt;

&lt;p&gt;As you can see, refactoring the duplication between two test suites now is almost a no-brainer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do you like to learn more about testing and TDD in Kotlin?&lt;/p&gt;

&lt;p&gt;I have written a 4-part (350-pages total) “&lt;a href="https://iwillteachyoukotlin.com"&gt;Ultimate Tutorial: Getting Started With Kotlin&lt;/a&gt;” (+ more to come), and you can get it as a free bonus by becoming a member of my monthly newsletter.&lt;/p&gt;

&lt;p&gt;On top of just Kotlin, it is full of goodies like TDD, Clean Code, Software Architecture, Business Impacts, 5 WHYs, Acceptance Criteria, Personas, and more.&lt;/p&gt;

&lt;p&gt;—Sign up here and &lt;a href="https://iwillteachyoukotlin.com"&gt;start learning how to build full-fledged Kotlin applications with TDD&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Now, I’m not trying you to convince of one style or another. I’m just trying to tell you that both styles have their strengths and weaknesses.&lt;/p&gt;

&lt;p&gt;And as we’ve noticed even strength of the style might let you shoot yourself in the foot. So be careful: with power comes responsibility.&lt;/p&gt;

&lt;p&gt;Don’t make your hierarchical tests too complex and too nested!&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Turn
&lt;/h2&gt;

&lt;p&gt;If you like my ideas, consider giving this article lots of dev.to reactions 😊 and share your own experiences with both styles in the comments below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What tricky situations with testing can YOU remember?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;originally published on &lt;a href="https://hackernoon.com/how-can-hierarchical-test-structure-absolutely-make-a-mess-f72f47b5bf57"&gt;HackerNoon&lt;/a&gt;&lt;br&gt;
picture credit: &lt;a href="https://www.pexels.com/photo/abstract-close-up-cobweb-connection-276502/"&gt;pexels&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>showdev</category>
      <category>testing</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>9 Rules of Effective Development Team Meetings</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Thu, 31 Jan 2019 06:28:37 +0000</pubDate>
      <link>https://dev.to/waterlink/4-rules-of-effective-development-team-meetings-25hn</link>
      <guid>https://dev.to/waterlink/4-rules-of-effective-development-team-meetings-25hn</guid>
      <description>&lt;p&gt;Let me ask you a question.&lt;/p&gt;

&lt;p&gt;Have you ever had a meeting scheduled 45 minutes after the stand-up? Have you been able to do any productive work before it?&lt;/p&gt;

&lt;p&gt;Hardly can get into any deep enough focus before such distraction. It’s frustrating, I know!&lt;/p&gt;

&lt;p&gt;Also, do you remember that time when some important decision was to be made at 7 freaking PM?? You didn’t have any energy and not so invested in making the best choice at this point, which is entirely fair at this time. &lt;/p&gt;

&lt;p&gt;Nor your colleagues.&lt;/p&gt;

&lt;p&gt;How successful was that decision then? Not so great, I guess.&lt;/p&gt;

&lt;p&gt;What do you think about heated discussions that can’t come to a close after 4-5 hours straight? Yeah, I know, you’re lucky to have had that lunch break in the middle…&lt;/p&gt;

&lt;p&gt;And how often did you feel that you shouldn’t have been invited to the meeting in the first place? Because you really don’t have anything to contribute or you trust others to make the right decision?&lt;/p&gt;

&lt;p&gt;If any of these questions evoke bad memories of worst meetings in you, then you’re in for a treat.&lt;/p&gt;

&lt;p&gt;Here is a short list of four rules to make your team’s meetings effective again:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Early in the morning, right after the stand-up.
&lt;/h2&gt;

&lt;p&gt;As a knowledge worker, you don’t want to have 30-60mins between your start of the day and important meeting. You’re likely not to be able to focus on anything deeply.&lt;/p&gt;

&lt;p&gt;It’s frustrating, I know!&lt;/p&gt;

&lt;p&gt;Also, if the decision is important, you want your people not to be tired when making it. Otherwise, they’ll be pretty bad decision-makers, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Short. Non-negotiable time limit.
&lt;/h2&gt;

&lt;p&gt;If you allow your meetings to run more than 15-60mins, then you’re likely to have 5-6 hours discussion where opposing sides with strongly-held opinions can’t agree on the decision.&lt;/p&gt;

&lt;p&gt;Put a hard time limit in place.&lt;/p&gt;

&lt;p&gt;This will force people to not waste time on what’s not important in the meeting.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The 2nd best decision is better than no decision at all.
&lt;/h2&gt;

&lt;p&gt;Have a team come up with &lt;em&gt;some&lt;/em&gt; decision, even if not everyone agrees. Adopt the mantra “A decision is better than no decision. We can always correct the course when we have more information.”&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Minimum viable audience.
&lt;/h2&gt;

&lt;p&gt;If you can make this decision with only 3 people instead of 12, then go for it, and pull people as you need them and if you need them only.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Contributed by commenters:&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. No meeting without an Agenda
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(by &lt;a href="https://dev.to/mrtnrdl"&gt;Martin Riedel&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you get an invite without agenda and unclear goal, just decline it. If somebody asks why tell them that there was no agenda.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Rule of the two feet
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(by &lt;a href="https://dev.to/dmerejkowsky"&gt;Dimitri Merejkowsky&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you feel like you can’t contribute to the meeting in any useful manner, or you don’t think that the meeting has any value for you or for your team/org, then just use your two feet—leave the meeting.&lt;/p&gt;

&lt;p&gt;Surely, everybody needs to understand this rule and accept that this might happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. No phubbing. No screens allowed other than presenter’s one.
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(by &lt;a href="https://dev.to/dmerejkowsky"&gt;Dimitri Merejkowsky&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Don’t use your phone or tablet—they’re forbidden. Some apps allow whole group to block their screens on their phones for the time of the meeting, and if somebody phubbs, then the entire group gets “punished” in some virtual way (for example, your virtual tree dies, and you have to start over).&lt;/p&gt;

&lt;p&gt;If the meeting needs a presenter’s laptop, this is alright. If you need to take notes, then do it on pen&amp;amp;paper.&lt;/p&gt;

&lt;p&gt;If you have somebody who protocols the meeting, they can have a protocol laptop (single-purpose device: there should be no distractions possible on such a laptop).&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Have a facilitator
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(by &lt;a href="https://dev.to/waterlink"&gt;Oleksii Fedorov&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Have a person responsible for running the meeting. This shouldn’t be a manager of any sort. The facilitator’s role is a role of servantship, not management.&lt;/p&gt;

&lt;p&gt;They’ll make sure that we’re not diverging too much from the agenda, keep track of time, and make sure to table discussions that are not going anywhere or are too disruptive for goals of the meeting.&lt;/p&gt;

&lt;p&gt;This person should be a rotating role so that every team member gets a chance to be one.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Manage your manager/stakeholder… if you have to
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(by &lt;a href="https://dev.to/waterlink"&gt;Oleksii Fedorov&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You know, that troublesome scenario where people avoid their commitments (decided from the meetings) pretending that they’ve forgotten or misunderstood, etc. This fosters a lot of negativity and conflict. Oh, and especially if they are a stakeholder or something like this.&lt;/p&gt;

&lt;p&gt;In this case, documenting all the decisions made is great, and sending them as an email to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure both parties are on the same page and wish to commit to this.&lt;/li&gt;
&lt;li&gt;To hold everyone accountable, including your stakeholder(s) or manager(s) later when “sh$t hits the fan.”&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Thank you for reading! If you liked this, please share the article on your favorite social media!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you improve your meetings? Share in the comments!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;(picture from Pexels)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Why Are Some Developers so Allergic to IDEs?</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Mon, 28 Jan 2019 06:58:25 +0000</pubDate>
      <link>https://dev.to/waterlink/why-are-some-developers-so-allergic-to-ides-24hl</link>
      <guid>https://dev.to/waterlink/why-are-some-developers-so-allergic-to-ides-24hl</guid>
      <description>&lt;p&gt;Countless times I meet developers who prefer simpler editors. And by “prefer” I mean that they have strong negative feelings towards any IDEs, especially the ones that one needs to pay money for.&lt;/p&gt;

&lt;p&gt;Now, it’s worth mentioning that my path through coding tools over the last 20 years went like this:&lt;/p&gt;

&lt;p&gt;Notepad -&amp;gt; Turbo Pascal Editor -&amp;gt; Delphi -&amp;gt; Visual Studio -&amp;gt; Gedit -&amp;gt; Sublime Text -&amp;gt; Vim -&amp;gt; Emacs -&amp;gt; Emacs (Evil mode) -&amp;gt; Atom -&amp;gt; Vim -&amp;gt; IntelliJ Idea (settled for now).&lt;/p&gt;

&lt;p&gt;The switch to IDE had happened when I attended a Software Craft meet-up. I’ve paired with another developer who’ve shown me something that looked like magic to me at a time.&lt;/p&gt;

&lt;p&gt;Basically, I’ve felt doubts about the tooling of my choice, since this IDE that was in front of me (in the hands of an experienced user) could allow me to do development at a 5x-10x rate of what I could currently.&lt;/p&gt;

&lt;p&gt;Now the question is: &lt;strong&gt;why do we, developers, feel such negative feelings towards a paid tool that can boost our productivity so much?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s discuss!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Try Kotlin in Java Backend Codebase Without Risk</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Wed, 16 Jan 2019 13:32:08 +0000</pubDate>
      <link>https://dev.to/waterlink/how-to-try-kotlin-in-java-backend-codebase-without-risk-1ecc</link>
      <guid>https://dev.to/waterlink/how-to-try-kotlin-in-java-backend-codebase-without-risk-1ecc</guid>
      <description>&lt;p&gt;Who’s heard of this lovely and astounding programming language Kotlin, and wanted to try it out on the real backend project and couldn’t?&lt;/p&gt;

&lt;p&gt;This is common. The team discusses that everyone really wants to go Kotlin, and they still decide to create that new codebase in Java. You and your fellow colleagues are afraid that this will go crazy wrong, right?&lt;/p&gt;

&lt;p&gt;And you are right to have such a feeling, as you don’t have enough confidence yet to make the switch. What if the whole team is still learning this new technology, and there is an unexpected challenge that nobody can resolve for weeks?&lt;/p&gt;

&lt;p&gt;Now, you’re probably quite a bit into this project, and your backend codebase is all in verbose Java, and you think: “No way I can try Kotlin now! Not until next one…”&lt;/p&gt;

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

&lt;p&gt;There is no point in waiting until the next opportunity because of the high chances that it’ll turn out the same!&lt;/p&gt;

&lt;p&gt;Now, what if I told you that you can still try out Kotlin together with your teammates in this codebase without any risks, and no strings attached?&lt;/p&gt;

&lt;p&gt;Let me explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mixing Java and Kotlin code
&lt;/h2&gt;

&lt;p&gt;With Kotlin’s 100% bidirectional interoperability, it’s possible to mix Java and Kotlin code easily.&lt;/p&gt;

&lt;p&gt;What this means, is that you can convert a single file from Java to Kotlin to get the feels of what it’ll look like. And everything will work just like before.&lt;/p&gt;

&lt;p&gt;Now, what if I told you that such a conversion is one hotkey away?&lt;/p&gt;

&lt;p&gt;Let me show an example. Imagine you had this simple service class in your Java backend application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// QuizService.java&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.iwillteachyoukotlin.quizzy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Service&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuizService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;QuizRepository&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;QuizService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;QuizRepository&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;quizRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BadRequestException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id should be empty"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="nf"&gt;getQuiz&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NotFoundException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"quiz not found"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can press &lt;code&gt;CMD+ALT+SHIFT+K&lt;/code&gt; (or &lt;code&gt;CTRL+ALT+SHIFT+K&lt;/code&gt;), or you could use &lt;code&gt;Convert Java File to Kotlin File&lt;/code&gt; action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AkLHoOL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-simple-conversion.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AkLHoOL_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-simple-conversion.gif" alt="Open Find Action tool, type convert to kotlin, press enter, and see the file fully convert to kotlin automatically" width="600" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result is the following code. Notice how both constructor and field definition has merged into a single declaration in Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// QuizService.kt&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.iwillteachyoukotlin.quizzy&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Service&lt;/span&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuizService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;quizRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;QuizRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;BadRequestException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id should be empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getQuiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orElseThrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;NotFoundException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"quiz not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note for Lombok users:&lt;/p&gt;

&lt;p&gt;Use Delombok on this file before converting to Kotlin.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course, you need to add Kotlin support to your build tool before you can even run this code:&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Kotlin support to Gradle
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(Note: refer to &lt;a href="https://kotlinlang.org/docs/reference/using-maven.html"&gt;this guide&lt;/a&gt; if you’re using Maven)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Add a Gradle plugin appropriately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s2"&gt;"org.jetbrains.kotlin.jvm"&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s2"&gt;"1.3.11"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note for Spring Boot users:&lt;/p&gt;

&lt;p&gt;You need to add this plugin, so that Kotlin classes will open automatically where needed, so that Spring Boot can use reflection on them:&lt;/p&gt;


&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s2"&gt;"org.jetbrains.kotlin.plugin.spring"&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s2"&gt;"1.3.11"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;And if you’re using JPA/Hibernate entities, you’ll need this plugin:&lt;/p&gt;


&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s2"&gt;"org.jetbrains.kotlin.plugin.jpa"&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s2"&gt;"1.3.11"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This adds the default constructor for your entities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, you’ll need to add a dependency on Kotlin standard library and reflection library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s2"&gt;"org.jetbrains.kotlin:kotlin-stdlib-jdk8"&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s2"&gt;"org.jetbrains.kotlin:kotlin-reflect"&lt;/span&gt;
    &lt;span class="c1"&gt;// …&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have one Kotlin file among the sea of Java files. Java classes are calling this Kotlin code, and this Kotlin code is calling to Java code.&lt;/p&gt;

&lt;p&gt;And it all perfectly works. And all tests pass!&lt;/p&gt;

&lt;p&gt;Now, simple automatic conversion is ok and all, but it’s not enough to really leverage the power of Kotlin.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Use Elvis operator instead of most null checks
&lt;/h2&gt;

&lt;p&gt;If you had any null check anywhere that &lt;code&gt;returns&lt;/code&gt; or &lt;code&gt;throws&lt;/code&gt; an exception, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;BadRequestException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id should not be empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These null checks that either &lt;code&gt;throw&lt;/code&gt; or &lt;code&gt;return&lt;/code&gt; are usually called guard &lt;code&gt;if&lt;/code&gt; statements. In Kotlin these can be done more succinctly with "Elvis" operator &lt;code&gt;?:&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;BadRequestException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id should not be empty"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Convert &lt;code&gt;Optional&lt;/code&gt;s to nullable
&lt;/h2&gt;

&lt;p&gt;Another example that can be simplified with Kotlin is the usage of &lt;code&gt;Optional&lt;/code&gt; type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getQuiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orElseThrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;NotFoundException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"quiz not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we’re going to use another method of our repository that returns either a found object or &lt;code&gt;null&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getQuiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;quizRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByIdOrNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;NotFoundException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"quiz not found"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, here we use the Elvis operator, as well. Quite handy, isn’t it?&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Make JUnit test names more readable
&lt;/h2&gt;

&lt;p&gt;Let’s imagine that the application above had this test in its integration test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;failsToCreate_whenIdIsProvided&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="n"&gt;quiz&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;Quiz&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"cta"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"https://example.org/image.png"&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ResultActions&lt;/span&gt; &lt;span class="n"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mockMvc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;perform&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/quizzes"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;APPLICATION_JSON_UTF8&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeValueAsString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isBadRequest&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;andExpect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.message"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;equalTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id should be empty"&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;Now, after automatic conversion to Kotlin it’ll look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="nd"&gt;@Throws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;failsToCreate_whenIdIsProvided&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;quiz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"cta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"https://example.org/image.png"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mockMvc&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/quizzes"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APPLICATION_JSON_UTF8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectMapper&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeValueAsString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quiz&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;andExpect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;isBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;andExpect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;jsonPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"$.message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id should be empty"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we can throw away this &lt;code&gt;@Throws&lt;/code&gt; annotation immediately. It’s mostly useless in Kotlin.&lt;/p&gt;

&lt;p&gt;And now, we can use actual human-readable sentences in the method names using backticks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`create&lt;/span&gt; &lt;span class="n"&gt;quiz&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;fails&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nf"&gt;provided`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// …&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My general structure is: "{method name or use case name} - {expected outcome} when {condition}."&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Use &lt;code&gt;lateinit&lt;/code&gt; instead of nullable
&lt;/h2&gt;

&lt;p&gt;In cases, when something is being provided later (like dependency injection, or initialized in the set-up section of the test suite), you should use &lt;code&gt;lateinit&lt;/code&gt; instead. It’s much cleaner.&lt;/p&gt;

&lt;p&gt;Look, this code is a result of automatic conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="nd"&gt;@RunWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SpringRunner&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuizzesIntegrationTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;WebApplicationContext&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;objectMapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;mockMvc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MockMvc&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="nd"&gt;@Before&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mockMvc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MockMvcBuilders&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;webAppContextSetup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// …&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All these fields are initialized later, AND before the first usage, so we can tell the compiler about that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;WebApplicationContext&lt;/span&gt;

&lt;span class="nd"&gt;@Autowired&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;objectMapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ObjectMapper&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;mockMvc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MockMvc&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;quizId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the problem is that all these nullable values were unsafely unwrapped everywhere in the test suite with &lt;code&gt;!!&lt;/code&gt; operator:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WCk2ZC_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-unnecessary-non-null-assertion-1024x497.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WCk2ZC_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-unnecessary-non-null-assertion-1024x497.png" alt="a lot of warnings about unnecessary non-null (!!) assertion" width="880" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, we can fix them all manually, but these are things that tools should fix for us.&lt;/p&gt;

&lt;p&gt;And they do, look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bhFxvWqe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-remove-unnecessary-non-null-assertion.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bhFxvWqe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-remove-unnecessary-non-null-assertion.gif" alt="use intent actions menu and select remove unnecessary non-null assertion, it removes !! automatically" width="600" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It still would be annoying to go through each occurrence though. So we should just apply code cleanups to the whole file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q345Mx9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-code-cleanup.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q345Mx9f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-code-cleanup.gif" alt="use find action tool and type code cleanup, the tool window shows up, select a single file only there, and proceed, all unnecessary non-null assertions disappear from the whole file" width="600" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Use named arguments for readability
&lt;/h2&gt;

&lt;p&gt;Now, you see this snippet of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;quiz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"cta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"https://example.org/image.png"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can make this code much more descriptive if we were to use named arguments, like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2UJ237uv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-add-names-to-call.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2UJ237uv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-add-names-to-call.gif" alt="use intent actions menu and choose to add names to call arguments, every argument now is named" width="600" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you’ll get this cute little readable snippet of code. Also, you can re-order the arguments when you pass them as you wish, and as it makes more sense.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;quiz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ctaText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;imageUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://example.org/image.png"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, to make this feature work, the class &lt;code&gt;Quiz&lt;/code&gt; can’t be a Java class, it has to be in Kotlin, so we’ll have to convert the entity below to Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"quizzes"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@RequiredArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@AllArgsConstructor&lt;/span&gt;
&lt;span class="nd"&gt;@JsonIgnoreProperties&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"hibernateLazyInitializer"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;ctaText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ctaText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;imageUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a result of full (auto + manual) conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"quizzes"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@JsonIgnoreProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hibernateLazyInitializer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Quiz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;@Id&lt;/span&gt;
        &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;ctaText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we’re getting rid of all the Lombok stuff and using a &lt;code&gt;data class&lt;/code&gt; now because it can do most of the things, you would need from the entity.&lt;/p&gt;

&lt;h2&gt;
  
  
  6+. There is so much more you can improve!
&lt;/h2&gt;

&lt;p&gt;If you want to learn more about how good Kotlin code will look like, I highly recommend to &lt;a href="https://play.kotlinlang.org/koans/overview"&gt;go through the Kotlin Koans&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can do that right in your browser, or in your IDE if you wish.&lt;/p&gt;

&lt;p&gt;Now, remember, at the beginning of this post, I’ve promised the "Without Risk" part, didn’t I?&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying out without any risks whatsoever
&lt;/h2&gt;

&lt;p&gt;Now, if I decided not to make the switch to Kotlin yet (because I still need to convince my colleagues, for example), I can use &lt;code&gt;Local History&lt;/code&gt; feature of my IDE to go back in time to when I started playing with Kotlin:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y94kowtU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-local-history-1024x548.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y94kowtU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-local-history-1024x548.png" alt="local history tool window" width="880" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To open that tool in IntelliJ, you can use the contextual menu on the whole project in the project structure tool. There is an option &lt;code&gt;Local History &amp;gt; Show History&lt;/code&gt; there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cPie50r1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-local-history-menu-1024x463.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cPie50r1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-local-history-menu-1024x463.png" alt="right click on the project name in the project structure tool, choose Local History - Show History" width="880" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you’ve found the place where you started playing with Kotlin, you can revert to the first Kotlin-related change, for example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RgKXr7hp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-local-history-revert.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RgKXr7hp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/how-to-try-kotlin-local-history-revert.png" alt="choosing revert option on a specific change in the past" width="664" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, there is not a single Kotlin file, and all the tests are passing. This is a handy feature in general if you screwed something up, and haven’t made a commit in Git in a while.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did that spike your curiosity about Kotlin?&lt;/p&gt;

&lt;p&gt;I have written a 4-part (350-pages total) “&lt;a href="https://iwillteachyoukotlin.com"&gt;Ultimate Tutorial: Getting Started With Kotlin&lt;/a&gt;” (+ more to come), and you can get it as a free bonus by becoming a member of my monthly newsletter.&lt;/p&gt;

&lt;p&gt;On top of just Kotlin, it is full of goodies like TDD, Clean Code, Software Architecture, Business Impacts, 5 WHYs, Acceptance Criteria, Personas, and more.&lt;/p&gt;

&lt;p&gt;—Sign up here and &lt;a href="https://iwillteachyoukotlin.com"&gt;start learning how to build full-fledged Kotlin applications&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Thank you and ask for you!
&lt;/h2&gt;

&lt;p&gt;Thank you so much for reading this article! I hope you enjoyed it. Please, tell me what you think about this in the comments!&lt;/p&gt;

&lt;p&gt;Also, it would make me so much happier share this post with your friends and colleagues who you think might benefit from it. Or you could share it on your favorite social media!&lt;/p&gt;

&lt;p&gt;You are welcome to &lt;a href="https://iwillteachyoukotlin.com/blog/"&gt;read my blog about Kotlin&lt;/a&gt;, and &lt;a href="http://www.tddfellow.com/"&gt;my blog about TDD and best software engineering practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And &lt;a href="https://www.linkedin.com/in/oleksii-fedorov-b0b81186/"&gt;let’s connect on LinkedIn&lt;/a&gt;: I post short weekly updates about software developer’s productivity and happiness, teamwork, mental health, and a bit about Kotlin.&lt;/p&gt;

&lt;p&gt;If you want to hear more of my opinions, &lt;a href="https://twitter.com/intent/follow?screen_name=waterlink000"&gt;follow me on Twitter&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://iwillteachyoukotlin.com/2019/01/16/how-to-try-kotlin-in-java-backend-codebase-without-risk/"&gt;iwillteachyoukotlin blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Kotlin: How Can a Programming Language be so Young And so Mature at The Same Time?</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Sat, 12 Jan 2019 09:48:06 +0000</pubDate>
      <link>https://dev.to/waterlink/kotlin-how-can-a-programming-language-be-so-young-and-so-mature-at-the-same-time-25j</link>
      <guid>https://dev.to/waterlink/kotlin-how-can-a-programming-language-be-so-young-and-so-mature-at-the-same-time-25j</guid>
      <description>&lt;p&gt;In this article, we’re going to explore why young programming languages with modern features can’t be adopted quickly. Additionally, we’re going to take a look at one exceptional example that got specific parameters right to be both young, modern and mature, just ready for adoption at small and big scale.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DISCLAIMER: Some details are omitted intentionally. Keep your mind open when reading. If something seems naive, or not entirely true, bear in mind that the author thought into both the front and back sides of the coin, and the unseen third side of the coin, as well. You’re welcome in comments for a more in-depth discussion—it’s going to be worth your time for sure!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We all know that most of us, software developers, love to chase after shiny things just as much as we like to build them. This is not different for programming languages.&lt;/p&gt;

&lt;p&gt;And, in this day and age, new young programming languages pop up like these mushrooms:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LcufJjiG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/young-mature-programming-language-cover-1024x768.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LcufJjiG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/young-mature-programming-language-cover-1024x768.jpeg" alt="" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why new modern languages can’t be adopted quickly?
&lt;/h2&gt;

&lt;p&gt;A distinct feature of a young language is that creators and community gets the chance to experiment with different features and designs to potentially fix some problems of the existing mature languages. Mind you, any solution to any problem will bring minimum two more subtle issues. So this cycle of continuous improvement will never end.&lt;/p&gt;

&lt;p&gt;While young languages can explore more advanced features and designs, they usually don’t have a robust ecosystem of libraries, frameworks, and tooling. Moreover, when the community develops these, people will still have to learn them, and that means that they (albeit temporarily) will be much less productive. And I’m not even going to talk about potential vulnerabilities, bugs, and so on.&lt;/p&gt;

&lt;p&gt;Now, wouldn’t it be great if the new young modern language could rely on the existing mature ecosystem? Wouldn’t it be fantastic if using existing libraries, frameworks and tooling was entirely natural and not awkward at all?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/intent/tweet?source=https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/&amp;amp;text=%E2%80%9CNow,%20wouldn%E2%80%99t%20it%20be%20great%20if%20the%20new%20young%20modern%20language%20could%20rely%20on%20the%20existing%20mature%20ecosystem?%E2%80%9D%0A%0A%E2%80%94https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/?q=1"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r-VpNSxY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/young-mature-programming-language-quote-1-1024x549.png" alt="" width="880" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you ask me these questions, I’ll tell you that you’re perhaps describing Kotlin. Kotlin is a programming language where you can naturally use any library, framework or tool from the JVM ecosystem without any awkwardness.&lt;/p&gt;

&lt;p&gt;Now, there were languages before, that could do that as well, like Scala, Groovy, Clojure, and so on. And they all got something wrong: natural use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why these languages don’t want to rely on the existing mature ecosystem?
&lt;/h2&gt;

&lt;p&gt;Either it wasn’t natural to use the same framework or library, or it was even impossible to use the same tooling. And in the scenario where it would be possible to use same tooling, framework, and libraries naturally; somehow, the majority of the community went out there and built new tools, frameworks, and libraries (I’m looking at you, Scala, and sbt).&lt;/p&gt;

&lt;p&gt;My hunch is that this happens because most of the early adopters of these new languages (“promised replacements for Java”) have somewhat an adversarial relationship with Java language and JVM ecosystem.&lt;/p&gt;

&lt;p&gt;They hate it.&lt;/p&gt;

&lt;p&gt;As early adopters, they set the playing field, because they are in the vast majority in the community during the first few years of the new young language. This way, they get to write all the brand new shiny tools, frameworks and libraries. And they are the ones who start new projects in these languages at actual companies and startups.&lt;/p&gt;

&lt;p&gt;This way, the community style sets in: unique tooling, frameworks, and sets of libraries that people use. Sometimes, these are even designed on purpose to be radically different from their older alternatives from the JVM community.&lt;/p&gt;

&lt;p&gt;This makes the learning curve very steep, and so the language gets adopted only by like-minded people, and poor developers who just have no choice but to maintain the codebases where this set of tools is being used already.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to attract different early adopters that will be happy to leverage existing ecosystem?
&lt;/h2&gt;

&lt;p&gt;Kotlin is radically different from this approach. The playing field rule number one: “100% bidirectional interoperability with Java and JVM ecosystem.”&lt;/p&gt;

&lt;p&gt;Thus the community attracts fellows who are not looking to do everything in the entirely different approach; instead, they want a  more modern language, AND they want to transfer their skills, knowledge, and experience from working with the mature ecosystem like JVM.&lt;/p&gt;

&lt;p&gt;These early adopters don’t want to rewrite their existing codebases entirely because they are large, so being able to write only new code in Kotlin, and keep older code in Java helps a lot!&lt;/p&gt;

&lt;h2&gt;
  
  
  Small story of a fellow software engineer
&lt;/h2&gt;

&lt;p&gt;I’m going to give you a tangible example:&lt;/p&gt;

&lt;p&gt;Clara is a software engineer, working for a big organization, mostly working with Java, JVM, and Spring Boot. Clara’s professional level is senior and perhaps even beyond that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;she applies best software practices,&lt;/li&gt;
&lt;li&gt;knows how to design simple software iteratively,&lt;/li&gt;
&lt;li&gt;can solve any complex problem you throw at her,&lt;/li&gt;
&lt;li&gt;knows her audience when writing the code (current and expected in the future level of her team members),&lt;/li&gt;
&lt;li&gt;excellent communicator and team player,&lt;/li&gt;
&lt;li&gt;teaches and mentors other developers,&lt;/li&gt;
&lt;li&gt;can take on the role of a team lead today,&lt;/li&gt;
&lt;li&gt;and lives the life of a life-long learner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Her current development workflow includes building the application and automating development tasks with Gradle, and she gets her coding done within a modern IDE like IntelliJ. She doesn’t have any of the adversarial feelings towards any of these tools and technologies.&lt;/p&gt;

&lt;p&gt;Quite the opposite: she loves them!&lt;/p&gt;

&lt;p&gt;Sometimes though, she feels feature envy to all these cool modern programming languages where you could have one-liner data classes, less boilerplate in general, and the null-pointer exception is not a dreaded threat at every step.&lt;/p&gt;

&lt;p&gt;And here is Kotlin programming language that recently became “production-ready.”&lt;/p&gt;

&lt;p&gt;So she tries out to build a tiny web app (a tad more complicated than “Hello world”). And it seems like she can still use the same build tool—Gradle; and she still can use any of her favorite libraries, and much more critical, she can use the same web framework—Spring Boot.&lt;/p&gt;

&lt;p&gt;And using all these things is not awkward at all, and feels just as natural, as in their “home” environment—Java.&lt;/p&gt;

&lt;p&gt;Now, she has the next question: “This language is great but quite new… do I have to lose all the great features of my IDE now?” Because that is what happens to most modern languages—the IDE support is lagging way… way behind.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/intent/tweet?source=https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/&amp;amp;text=%E2%80%9CThis%20language%20is%20great,%20but%20quite%20new%E2%80%A6%20do%20I%20have%20to%20lose%20all%20the%20great%20features%20of%20my%20IDE%20now?%E2%80%9D%0A%0A%E2%80%94https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/?q=2"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sjqvb9P6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/young-mature-programming-language-quote-4-1024x549.png" alt="" width="880" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now she gets pleasantly surprised: 95% of the IDE features that she needs are there and are supported:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;basic and advanced refactorings,&lt;/li&gt;
&lt;li&gt;jump to definition, &lt;/li&gt;
&lt;li&gt;find usages, &lt;/li&gt;
&lt;li&gt;running application and tests from IDE, &lt;/li&gt;
&lt;li&gt;running a single test in the current context,&lt;/li&gt;
&lt;li&gt;debugger,&lt;/li&gt;
&lt;li&gt;code completion, even cross-language,&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this makes so much sense because the language is developed by the same company that develops the IDE (JetBrains). This certainly ensures that the tooling will be at least somewhat up to speed with the new modern language.&lt;/p&gt;

&lt;p&gt;“This all sounds great!” Clara thinks, “Do I have to rewrite my application at work now fully to Kotlin?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Most important playing field rules fostering the adoption
&lt;/h2&gt;

&lt;p&gt;And she gets pleasantly surprised here as well. All she really needs to do is to add Kotlin Gradle plugin (few lines of change in a single file), and she can start adding Kotlin files to the source code base. All the old files, written in Java, are still working correctly.&lt;/p&gt;

&lt;p&gt;Moreover, cross-language calls are working out of the box: she can call Java code from Kotlin, and Kotlin code from Java; AND it all feels just as natural. At almost no point, the calling code is even aware that it is calling one or the other because there is no difference.&lt;/p&gt;

&lt;p&gt;That is what making “100% interoperability” a most significant playing field rule right from the beginning can do for the new modern language! &lt;/p&gt;

&lt;p&gt;So if you’re going to design a new programming language, I suggest you consider imbuing it as one of the top priorities, as it will allow for much better adoption. And what creator of the library, tool, or language doesn’t want this kind of adoption superpower? ;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/intent/tweet?source=https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/&amp;amp;text=%E2%80%9CAnd%20what%20creator%20of%20the%20library,%20tool,%20or%20language%20doesn%E2%80%99t%20want%20this%20kind%20of%20adoption%20superpower?%E2%80%9D%0A%0A%E2%80%94https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/?q=3"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6jAzol2H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/young-mature-programming-language-quote-2-1024x549.png" alt="" width="880" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you could notice, Clara is not looking for an entirely radically different approach to coding, and instead, she is looking for a way to keep 75% of what is working well, and perhaps use a few more modern features of the language to improve the other 25% significantly.&lt;/p&gt;

&lt;p&gt;This could be reducing the amount of the boilerplate by letting the language figure out the obvious so that you don’t have to specify it every time. This could also be a different decision to make everything an expression, which makes specific scenarios much more ergonomic and more comfortable to read, for example, try-catch block, where you need to set a variable in the “try” part and rethrow an enhanced error in the “catch” part.&lt;/p&gt;

&lt;p&gt;These things and more are improving the readability significantly.&lt;/p&gt;

&lt;p&gt;Additionally, the ability to have first-class immutable variables and nullable/non-nullable types eliminates whole classes of possible mistakes and errors. It is fantastic!&lt;/p&gt;

&lt;h2&gt;
  
  
  Stand on the shoulders of the giants!
&lt;/h2&gt;

&lt;p&gt;Most of the modern languages are created to be used standalone, detached from the existing library and tooling ecosystem, either by design or “forced” by community guidelines or culture.&lt;/p&gt;

&lt;p&gt;These modern languages might see some adoption, but they will eventually die out or stay in the small niche because the majority of professionals will just continue using the mature ones because they have better support for literally everything. There are rare, infrequent, exceptions from this rule.&lt;/p&gt;

&lt;p&gt;If the new programming language wants to stay strong, it needs to stand on the shoulders of the giants.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/intent/tweet?source=https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/&amp;amp;text=%E2%80%9CInstead%20of%20going%20against%20the%20former%20mature%20language,%20and%20doing%20everything%20differently,%20leverage%20as%20much%20as%20you%20can%20from%20the%20mature%20ecosystem,%20and%20add%20more%20value%20on%20top%20of%20that.%E2%80%9D%0A%0A%E2%80%94https://iwillteachyoukotlin.com/kotlin-young-and-mature-programming-language-at-the-same-time/?q=4"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f1wYh0TU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://iwillteachyoukotlin.com/wp-content/uploads/2019/01/young-mature-programming-language-quote-3-1024x549.png" alt="" width="880" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, instead of going against the former mature language, and doing everything differently, leverage as much as you can from the mature ecosystem, and add more value on top of that. This way, people, when learning this language don’t have to give up anything, and they only stand to gain— a real win-win situation!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did that spike your curiosity about Kotlin?&lt;/p&gt;

&lt;p&gt;I have written a 4-part (350-pages total) “&lt;a href="https://iwillteachyoukotlin.com"&gt;Ultimate Tutorial: Getting Started With Kotlin&lt;/a&gt;” (+ more to come), and you can get it as a free bonus by becoming a member of my monthly newsletter.&lt;/p&gt;

&lt;p&gt;On top of just Kotlin, it is full of goodies like TDD, Clean Code, Software Architecture, Business Impacts, 5 WHYs, Acceptance Criteria, Personas, and more.&lt;/p&gt;

&lt;p&gt;—Sign up here and &lt;a href="https://iwillteachyoukotlin.com"&gt;start learning how to build full-fledged Kotlin applications&lt;/a&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Thank you and ask for you!
&lt;/h2&gt;

&lt;p&gt;Thank you so much for reading this article! I hope you enjoyed it. Please, tell me what you think about this in the comments!&lt;/p&gt;

&lt;p&gt;Also, it would make me so much happier if you could share this post with your friends and colleagues who you think might benefit from it. Or you could share it on your favorite social media!&lt;/p&gt;

&lt;p&gt;You are welcome to &lt;a href="https://iwillteachyoukotlin.com/blog/"&gt;read my blog about Kotlin&lt;/a&gt;, and &lt;a href="http://www.tddfellow.com/"&gt;my blog about TDD and best software engineering practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And &lt;a href="https://www.linkedin.com/in/oleksii-fedorov-b0b81186/"&gt;let’s connect on LinkedIn&lt;/a&gt;: I post short weekly updates about software developer’s productivity and happiness, teamwork, mental health, and a bit about Kotlin.&lt;/p&gt;

&lt;p&gt;If you want to hear more of my opinions, &lt;a href="https://twitter.com/intent/follow?screen_name=waterlink000"&gt;follow me on Twitter&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://iwillteachyoukotlin.com/2019/01/07/kotlin-how-can-a-programming-language-be-so-young-and-so-mature-at-the-same-time/"&gt;iwillteachyoukotlin.com blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;cover image source: &lt;a href="https://www.pexels.com/photo/forest-moss-mushrooms-tree-stump-62315/"&gt;pexels&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>kotlin</category>
      <category>java</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How Kotlin Calamity Devours Your Java Apps Like Lightning?</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Sat, 18 Nov 2017 22:18:29 +0000</pubDate>
      <link>https://dev.to/waterlink/how-kotlin-calamity-devours-your-java-apps-like-lightning-8fd</link>
      <guid>https://dev.to/waterlink/how-kotlin-calamity-devours-your-java-apps-like-lightning-8fd</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published &lt;a href="https://hackernoon.com/how-kotlin-calamity-devours-your-java-apps-like-cancer-f3ce9500a028"&gt;on Hackernoon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I hear what you are saying. There is that buzz around Android actively adopting Kotlin as a primary programming language. And &lt;a href="https://fossbytes.com/kotlin-surpass-java-android-programming/"&gt;trends&lt;/a&gt; don’t look good either.&lt;/p&gt;

&lt;p&gt;Things on a web-development front are not by a bit better. &lt;a href="https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0"&gt;Most popular web-framework in Java supports more and more idiomatic Kotlin as we speak&lt;/a&gt; by providing suitable APIs.&lt;/p&gt;

&lt;p&gt;You can feel they are making their bet for the future.&lt;/p&gt;

&lt;p&gt;And it seems that this future is closer than you think.&lt;/p&gt;

&lt;p&gt;Now you are thinking. Should I make that bet, as well? Or is it just some hype that will die out in a year?&lt;/p&gt;

&lt;p&gt;That little mixed controversial sensation in your heart. It just keeps worrying you.&lt;/p&gt;

&lt;p&gt;You are unsure and afraid that if you don’t do something, then that new hire who is excited about Kotlin will convert your code base to Kotlin, and you’ll lose your productivity as a result.&lt;/p&gt;

&lt;p&gt;That makes you worry about your job position.&lt;/p&gt;

&lt;p&gt;On the contrary, you felt disappointed in previous programming language attempts to replace Java. You feel discouraged to trust new such attempt. There is no chance a new language can make its way to most of the legacy code bases or is there?&lt;/p&gt;

&lt;p&gt;Perhaps, you feel curious about why tech giants (such as Google and Spring Team) place their bet on Kotlin.&lt;/p&gt;

&lt;p&gt;Could it be that you are new to the code base, and still learning some new technologies you haven’t used before? And there are few Kotlin enthusiasts on your team, who have already started converting Java code to Kotlin code?&lt;/p&gt;

&lt;p&gt;And the rate of said conversion is alarming?&lt;/p&gt;

&lt;p&gt;That makes you feel confused and angry. You already have a lot of moving parts that you have to learn on your plate. That just adds more.&lt;/p&gt;

&lt;p&gt;If you don’t spend time learning Kotlin, you are afraid that you’ll have to transfer to a different project, which still uses Java. For now.&lt;/p&gt;

&lt;p&gt;If you do learn Kotlin, you are terrified it will be time wasted, as it will not take off as everyone promises.&lt;/p&gt;

&lt;p&gt;I know, right?&lt;/p&gt;

&lt;h3&gt;
  
  
  How Can That New Team Member Convert The Whole Code Base to Kotlin in a Few Months?
&lt;/h3&gt;

&lt;p&gt;So can one team member make such a drastic change to your legacy code base?&lt;/p&gt;

&lt;p&gt;I mean, it is huge! There is no way a person can convert it all in the new language. So I can always stay mostly productive because the majority of the code will be in Java, right?&lt;/p&gt;

&lt;p&gt;Wrong!&lt;/p&gt;

&lt;p&gt;For you to understand how quickly Kotlin can consume your legacy Java application, I’m going to attach this image. It describes perfectly what I’ve seen so far:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2w4n57JR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Ak42m-mM4WV2Nw-FsGaKtuw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2w4n57JR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Ak42m-mM4WV2Nw-FsGaKtuw.jpeg" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;“How quickly Kotlin consumes Java applications.” (source: &lt;a href="https://www.pexels.com/photo/blue-clouds-color-danger-268774/"&gt;https://www.pexels.com/photo/blue-clouds-color-danger-268774/&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Kotlin is the programming language built by &lt;a href="http://jetbrains.com/"&gt;JetBrains&lt;/a&gt;. They have quite a vast Java code base, as well. They made it their mission to create a language that they can use today in their code base. Not just for the new features.&lt;/p&gt;

&lt;p&gt;How do you convert a Java file to Kotlin then?&lt;/p&gt;

&lt;p&gt;Probably, you write the same thing again in the new language. Then make all tests pass. That is pretty time-consuming. No way your project manager will allow such effort without a strong reason. Right?&lt;/p&gt;

&lt;p&gt;Nope.&lt;/p&gt;

&lt;p&gt;One hotkey.&lt;/p&gt;

&lt;p&gt;You’ve heard me right. It takes one keypress in IntelliJ to convert the Java file to Kotlin file. And in 99% of the cases, all the tests will still pass.&lt;/p&gt;

&lt;p&gt;You know what’s scarier?&lt;/p&gt;

&lt;p&gt;That works for the whole package, as well…&lt;/p&gt;

&lt;p&gt;Let me tell you a story.&lt;/p&gt;

&lt;p&gt;I have joined the project that had such a Kotlin enthusiast. They have convinced other team members to “try out” Kotlin for a single feature.&lt;/p&gt;

&lt;p&gt;The project was two and half years old. The size of a project was big enough to have multiple Gradle modules, and start extraction of some independent services.&lt;/p&gt;

&lt;p&gt;In two months nobody on the team was writing any Java anymore. Any Java file that needed to be changed to implement a user story was converted to Kotlin on sight.&lt;/p&gt;

&lt;p&gt;It is important to say that team’s velocity didn’t drop during these two months, as it didn’t take much time and effort to do the conversion. Especially, for Kotlin enthusiasts. They do such conversions all the time.&lt;/p&gt;

&lt;p&gt;Let me tell you another story.&lt;/p&gt;

&lt;p&gt;This time it was a non-successful conversion to Kotlin, for a change. But there is a catch, though.&lt;/p&gt;

&lt;p&gt;A few Kotlin enthusiasts joined the team at the same time. As they were already pretty experienced in converting Java to Kotlin, they just started doing it.&lt;/p&gt;

&lt;p&gt;The other half of team members were still learning the tech stack, as they were quite new on that code base. Kotlin was just adding other moving parts.&lt;/p&gt;

&lt;p&gt;They have resisted the change to Kotlin. The team agreed not to continue the conversion, as it will slow down getting these team members up to speed with already existing technology.&lt;/p&gt;

&lt;p&gt;But here is the catch.&lt;/p&gt;

&lt;p&gt;Upon one-on-one conversation, these team members liked Kotlin. And they were open to continuing the conversion once they feel more comfortable with the tech stack.&lt;/p&gt;

&lt;p&gt;I’m pretty confident in about half a year they will stop writing any Java, as well.&lt;/p&gt;

&lt;p&gt;Let me tell you the last story for today.&lt;/p&gt;

&lt;p&gt;It was a long-running project. Quite big and complex. I would consider it a legacy Java code base with more than ten macro-services (notice “macro” — not “micro”).&lt;/p&gt;

&lt;p&gt;One day, two team members asked a Kotlin enthusiast to help them try out Kotlin. They were curious because of all the buzz on the internet. And because that Kotlin enthusiast radiated passion about Kotlin.&lt;/p&gt;

&lt;p&gt;You can guess what has happened.&lt;/p&gt;

&lt;p&gt;In five months, nobody was writing Java code anymore on that team. Same story.&lt;/p&gt;

&lt;p&gt;And you know what is even more terrifying about that conversion? Once you’ve converted to Kotlin and started using Kotlin-exclusive features, it becomes hard to convert that code back to Java.&lt;/p&gt;

&lt;p&gt;There were enough of these would-be Java replacements in the past. And they’ve all failed to deliver on that promise.&lt;/p&gt;

&lt;p&gt;So what so different about Kotlin?&lt;/p&gt;

&lt;h3&gt;
  
  
  How is This Java Replacement Attempt Different From Previous?
&lt;/h3&gt;

&lt;p&gt;A few words.&lt;/p&gt;

&lt;p&gt;100% Java interoperability.&lt;/p&gt;

&lt;p&gt;You can easily have a mix of Kotlin and Java files in the same directory.&lt;/p&gt;

&lt;p&gt;Java can import Kotlin classes and use them as if they were Java classes without any weird syntax or tricks. The same goes for Kotlin. Kotlin code can import any of your Java classes and use them regularly as if they were Kotlin classes.&lt;/p&gt;

&lt;p&gt;There are no weird things like &lt;code&gt;object.field_$eq(value)&lt;/code&gt; to set a value.&lt;/p&gt;

&lt;p&gt;To invoke a Java setter from Kotlin, you will use Kotlin syntax: &lt;code&gt;object.field = value&lt;/code&gt;. And to invoke a Kotlin setter from Java, you will just use normal setter method: &lt;code&gt;object.setField(value)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Kotlin code can implement Java interfaces and Java code can implement Kotlin interfaces.&lt;/p&gt;

&lt;p&gt;Kotlin has that interoperability as a top-priority feature of the language. That is because JetBrains team wanted to use Kotlin on their vast Java codebase right away. And without any pain.&lt;/p&gt;

&lt;p&gt;That enables you to convert only a single class from Java to Kotlin and not trigger humongous cascading changes. Sometimes you would still want to convert a few related files, but you don’t have to.&lt;/p&gt;

&lt;p&gt;Another reason why Kotlin is more likely to deliver on the promise of replacing Java is build tooling.&lt;/p&gt;

&lt;p&gt;Kotlin doesn’t need any unique build tooling. A Maven or Gradle plugin is sufficient.&lt;/p&gt;

&lt;p&gt;Moreover, Kotlin’s build times are extremely fast. It can be even faster than Java if you have incremental compilation enabled!&lt;/p&gt;

&lt;p&gt;Alright. As you can see, there are not so much of negative points on the scale of the trade-off with Kotlin.&lt;/p&gt;

&lt;p&gt;So what is on the positive side of the scale? What do you get when you stop writing Java and start writing Kotlin?&lt;/p&gt;

&lt;p&gt;So why tech giants like Android and Spring are placing their bet on Kotlin?&lt;/p&gt;

&lt;h3&gt;
  
  
  So Why Tech Giants Are Placing Their Bet on Kotlin?
&lt;/h3&gt;

&lt;p&gt;Kotlin language is concise. It is concise without losing the readability of Java. Kotlin removes all the boilerplate that you see in a regular Java or Android application.&lt;/p&gt;

&lt;p&gt;Ever wanted stream API to be available directly on collection objects? Kotlin has that. Its standard library extends quite a few standard Java classes with additional functionality.&lt;/p&gt;

&lt;p&gt;That reduces boilerplate by a lot. Where you had to create five different classes to read a stream, Kotlin allows you just to do what you expect. To read that stream.&lt;/p&gt;

&lt;p&gt;Kotlin is safer than Java. It promotes nullability to the type system. That means that compiler can statically analyze your code and if you have a chance of a null-pointer exception somewhere — Kotlin code won’t compile.&lt;/p&gt;

&lt;p&gt;And these nullability checks are not even annoying like they are in other languages.&lt;/p&gt;

&lt;p&gt;That is thanks to smart casts. Let me show you an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--We1buIBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Ai-TND_5-Gm3IbckzPMq2HQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--We1buIBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Ai-TND_5-Gm3IbckzPMq2HQ.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Compile error because quiz variable can be null&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;quizStorage.load(quizId)&lt;/code&gt; returns &lt;code&gt;Quiz?&lt;/code&gt; (a nullable &lt;code&gt;Quiz&lt;/code&gt;) the compiler complains that you can’t directly call methods on &lt;code&gt;quiz&lt;/code&gt; variable because it can be &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So to make the compiler happy you will need to add a null check:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--07tbKjYG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A_2Bo4_56OChwP8BZdaDjkQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--07tbKjYG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A_2Bo4_56OChwP8BZdaDjkQ.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;By adding null-check we are fixing the compile error and making quiz “smart-casted” to non-nullable&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you can see, &lt;code&gt;quiz.moveToNextQuestion()&lt;/code&gt; is highlighted in a “special” way. If you hover over that variable, it will tell you that it has been smart-casted to &lt;code&gt;Quiz&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Because compiler knows now, that &lt;code&gt;quiz&lt;/code&gt; variable cannot be &lt;code&gt;null&lt;/code&gt; at this point.&lt;/p&gt;

&lt;p&gt;In different languages with nullable types, you typically need to unwrap the nullable value to non-nullable. Even after you made a null-check!&lt;/p&gt;

&lt;p&gt;Such unwrap operation is unsafe. And therefore, another programmer (including your future self) won’t be warned if they remove your null-check.&lt;/p&gt;

&lt;p&gt;Smart casts are cool with that. As soon as someone removes the null-check — there will be a compile error.&lt;/p&gt;

&lt;p&gt;And there is a much more concise way to write the same thing — elvis operator &lt;code&gt;?:&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gnLss1GP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Ax9ilZhAN1nZ_P0m28-VgwQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gnLss1GP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Ax9ilZhAN1nZ_P0m28-VgwQ.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Most null-checks can be eliminated using elvis operator to further simplify the code&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By the way, these examples are from my Ultimate Tutorial: Getting Started With Kotlin. It is a three-part tutorial in the form of e-book totaling 260 (and more in the future) pages of hands-on content that you can follow along.&lt;/p&gt;

&lt;p&gt;By this point, if you are interested in learning Kotlin, &lt;a href="https://iwillteachyoukotlin.com/ultimate-tutorial-getting-started-with-kotlin-kilac"&gt;download that Ultimate Kotlin Tutorial as a PDF here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Not only you are going to get hands-on content from which you will learn to program in Kotlin. You will be able to ask me any question when you are stuck, and I will help you.&lt;/p&gt;

&lt;p&gt;Anyways. What is there more to Kotlin benefits?&lt;/p&gt;

&lt;p&gt;Apparently, if you spend enough time writing Kotlin, you will start writing more readable and robust Java code, as well.&lt;/p&gt;

&lt;p&gt;That is an interesting side-effect, isn’t it?&lt;/p&gt;

&lt;p&gt;A few friends of mine, even told me, that they would prefer to hire Kotlin developer over Java developer for the project that is all Java and doesn’t have Kotlin at all.&lt;/p&gt;

&lt;p&gt;Moreover, &lt;a href="https://hackernoon.com/how-effective-java-may-have-influenced-the-design-of-kotlin-part-1-45fd64c2f974"&gt;Kotlin took a lot of principles from “Effective Java” book and converted them to basic language concepts&lt;/a&gt;. So by just writing Kotlin for some time, you are going to learn how to write a better Java code. Not so bad, right?&lt;/p&gt;

&lt;p&gt;So what about the tooling? Is it easy to use Kotlin? Or will I have to give up my refactoring and Intelligent powers of my IDE to code in Kotlin?&lt;/p&gt;

&lt;p&gt;Am I going to have to write it like in a text editor again?&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Kotlin is made by JetBrains. It is the same company that made IntelliJ IDEA. They did their hardest to make sure you will feel at home when using Kotlin in IntelliJ.&lt;/p&gt;

&lt;p&gt;Current support is humongous. All the essential refactorings are already in place.&lt;/p&gt;

&lt;p&gt;And, as we speak, they add more and more.&lt;/p&gt;

&lt;p&gt;So is it a good time to learn some Kotlin now?&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it a Good Idea For You to Learn Kotlin Right Now?
&lt;/h3&gt;

&lt;p&gt;Of course, you will need to decide.&lt;/p&gt;

&lt;p&gt;If you were to ask me… In your shoes, I would go for it. Here is why.&lt;/p&gt;

&lt;p&gt;Even if Kotlin doesn’t deliver on the promise of replacing Java in most of the legacy code bases (or even for new ones), I know I’ve become a better Java programmer.&lt;/p&gt;

&lt;p&gt;Only that should make it worthwhile. Do you need more?&lt;/p&gt;

&lt;p&gt;I have that for you.&lt;/p&gt;

&lt;p&gt;For a programmer it is always worthwhile to be learning another language at any point in time. The only exception is if you are only just starting out.&lt;/p&gt;

&lt;p&gt;So if you are comfortable with your language, tech stack, and everything, and you are not learning any other programming language at the moment, it is a great idea to get your hands dirty with Kotlin.&lt;/p&gt;

&lt;p&gt;It is going to put things into perspective and take you out of your current bubble. It is always good.&lt;/p&gt;

&lt;p&gt;Learning is a skill. So the more you learn, the better and more efficient learner you become.&lt;/p&gt;

&lt;p&gt;Perhaps, you think you don’t have the time to learn a new skill because you have a full-time job, family, hobby, and everything else in your life?&lt;/p&gt;

&lt;p&gt;Then you should &lt;a href="https://hackernoon.com/how-to-find-the-time-to-learn-a-new-skill-when-you-are-working-full-time-d1957060ced0"&gt;learn how to find the time to learn a new skill when you are working full-time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you think you are up to the challenge of upgrading yourself from Java developer to Kotlin developer, &lt;a href="https://iwillteachyoukotlin.com/ultimate-tutorial-getting-started-with-kotlin-kilac"&gt;download the Ultimate Tutorial: Getting Started With Kotlin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I genuinely thank you for reading, and I encourage you to give Kotlin a try. You have nothing to lose, anyway. And you can only benefit from that.&lt;/p&gt;

&lt;p&gt;If you want to make me happy, then you can share it with your friends, on social networks, hacker news, Reddit, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published &lt;a href="https://hackernoon.com/how-kotlin-calamity-devours-your-java-apps-like-cancer-f3ce9500a028"&gt;on Hackernoon&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>java</category>
      <category>android</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Never Fail At The Fizzbuzz Interview Challenge</title>
      <dc:creator>Alex Fedorov</dc:creator>
      <pubDate>Wed, 11 Oct 2017 20:11:32 +0000</pubDate>
      <link>https://dev.to/waterlink/how-to-never-fail-at-the-fizzbuzz-interview-challenge-62o</link>
      <guid>https://dev.to/waterlink/how-to-never-fail-at-the-fizzbuzz-interview-challenge-62o</guid>
      <description>&lt;p&gt;Ah, the classic FizzBuzz coding challenge.&lt;/p&gt;

&lt;p&gt;I’ve decided to include this picture to get your attention. Oh, and also because it associates with the “Buzz” part of the challenge.&lt;/p&gt;

&lt;p&gt;“Buzz” – alarm clock…&lt;/p&gt;

&lt;p&gt;Onward! Do you know that you don’t have even a single excuse to fail at one of these? So you think that you know that coding kata well?&lt;/p&gt;

&lt;p&gt;Let your imagination run wild:&lt;/p&gt;

&lt;p&gt;You are at the coding interview, and the interviewer has just asked you to implement FizzBuzz and given you the following problem description:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write a program that prints a sequence of numbers from 1 to N.&lt;/p&gt;

&lt;p&gt;Every number that divides by the three should appear as “Fizz.”&lt;/p&gt;

&lt;p&gt;Every number that divides by the five should appear as “Buzz.”&lt;/p&gt;

&lt;p&gt;Every number that divides by the three and the five should appear as “FizzBuzz.”&lt;/p&gt;

&lt;p&gt;– anonymous interviewer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A piece of cake!&lt;/p&gt;

&lt;p&gt;So you are writing away, and the code is pouring out of you…&lt;/p&gt;

&lt;p&gt;Five or ten minutes in and you are done. You feel the interviewer might just suspect that you were ready for the challenge. In that case, they will have some additional unexpected requirements for you.&lt;/p&gt;

&lt;p&gt;Just like in the real world programming.&lt;/p&gt;

&lt;p&gt;Continue reading, and we will explore these additional requirements and possible solution for them. And for now, we will solve the FizzBuzz challenge in Kotlin.&lt;/p&gt;

&lt;p&gt;It is probably a good idea to have some automated tests so that we know when we are done. Let’s create a new test suite in JUnit4:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Assert.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;

&lt;span class="nd"&gt;@Suppress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FunctionName"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are going to write a first test – the simplest one, that covers the fact that we can produce a normal number sequence without any “fizzes” or “buzzes”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`simple&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I like to split my tests in three sections: arrange, act and assert. It is not necessary to write out loud these comments as I do here. I don’t usually do myself so, but I think about these three sections when constructing a good test.&lt;/p&gt;

&lt;p&gt;On the other hand, I highly recommend you DO split your tests in such three sections. And write down these comments too for the sake of explicitness.&lt;/p&gt;

&lt;p&gt;If you are already comfortable writing great tests, feel free to ignore my advice.&lt;/p&gt;

&lt;p&gt;Onward! There are few compile errors in this test that we will need to deal with. First, we haven’t defined &lt;code&gt;FizzBuzz&lt;/code&gt; class yet. Second, we will need to create the &lt;code&gt;generateSequence&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Just to make things compile, we will make that method return an empty list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;emptyList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run our test. As expected, it fails because we are expecting a list with two items &lt;code&gt;["1", "2"]&lt;/code&gt;, but we are getting an empty list &lt;code&gt;[]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Making this pass is pretty simple. We are going to generate a sequence from one to &lt;code&gt;size&lt;/code&gt; using Kotlin’s range syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we are going to generate a new sequence out of it by calling &lt;code&gt;toString()&lt;/code&gt; method on every item of that sequence. To do that we are going to employ &lt;code&gt;map&lt;/code&gt; function defined on any Kotlin sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, by the way.&lt;/p&gt;

&lt;p&gt;Wondering what all these neat features of Kotlin are? Maybe you want to learn how to build a full-fledged application in Kotlin?&lt;/p&gt;

&lt;p&gt;I have accidentally written this 80-page hands-on getting started tutorial for Kotlin. Feel welcome to &lt;a href="https://iwillteachyoukotlin.com"&gt;download the free PDF Ultimate Tutorial: Getting Started With Kotlin&lt;/a&gt;. You are going to learn how to build a full-fledged command-line application in Kotlin. You’ll get free access preview for Web app and Android app tutorials, as well!&lt;/p&gt;

&lt;p&gt;Anyways, we should run our tests now.&lt;/p&gt;

&lt;p&gt;And they all pass.&lt;/p&gt;

&lt;p&gt;Alright. Our next step is to start handling some “fizz” numbers. For that, we can write a new test. It is as simple as copy-pasting (oh no!) the previous test and making some modifications to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`fizz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are going from one to four, and we are expecting all numbers to be normal except for number three. It should become “Fizz” in the generated sequence.&lt;/p&gt;

&lt;p&gt;If we run this test, it is going to fail, because so far we are producing only simple numbers converted to strings.&lt;/p&gt;

&lt;p&gt;To make this test pass we are going to extract &lt;code&gt;it.toString()&lt;/code&gt; part into a private method &lt;code&gt;generateMethod(number: Int): String&lt;/code&gt;. We will add an “if” statement to handle the case when the number divides by three:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It passes the test suite now.&lt;/p&gt;

&lt;p&gt;Next, we would like to write a test for the “Buzz” requirement. For that, we are going to generate a sequence from one to fourteen. There will be a few “fizzes” and “buzzes” there.&lt;/p&gt;

&lt;p&gt;No “fizzbuzzes” yet, though.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`buzz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That test fails because we are not producing any “buzzes” yet. We will add another “if” statement to handle that case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the test is passing.&lt;/p&gt;

&lt;p&gt;Finally, we want to write a test involving some “fizzbuzzy” numbers. In this case, we want to generate a sequence from one to thirty-one, so that we include at least two of these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`fizz&lt;/span&gt; &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"23"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"31"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And of course it does not work.&lt;/p&gt;

&lt;p&gt;That is because the first “if” statement (for “fizzes”) catches this case and produces “Fizz.” To fix that we will have to write a new “if” statement that handles the case for “fizzes” and “buzzes” at the same time.&lt;/p&gt;

&lt;p&gt;That case will have to be checked before all others. That way, nor “Fizz,” nor “Buzz,” will match before it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alrighty! All tests are passing now.&lt;/p&gt;

&lt;p&gt;Let’s extract some duplication in the test suite. Notably, the &lt;code&gt;ARRANGE&lt;/code&gt; part. That is because it is the same for every single test. We will promote &lt;code&gt;fizzBuzz&lt;/code&gt; local variable to the private field of the test suite class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Assert.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;

&lt;span class="nd"&gt;@Suppress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FunctionName"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`simple&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ACT&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`fizz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ACT&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`buzz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ACT&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`fizz&lt;/span&gt; &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ACT&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"13"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"23"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"31"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run the tests, they should still pass. As our next step, we should take a careful look if there is any duplication in the production code.&lt;/p&gt;

&lt;p&gt;And there is some!&lt;/p&gt;

&lt;p&gt;The checks for “fizziness” and “buzziness” are duplicated between “fizzbuzz” case handler and corresponding “fizz” or “buzz” case handler. Simplest refactoring we can do is to extract these into private functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At that point, you were about to refactor some more, for example, extract magic strings to constants.&lt;/p&gt;

&lt;p&gt;But the interviewer told you it is enough refactoring.&lt;/p&gt;

&lt;p&gt;You see they are impressed. You have finished earlier after all. But you feel as if the interviewer is a little bit suspicious. It is a classic exercise after all.&lt;/p&gt;

&lt;p&gt;So they decide to give you an additional requirement!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A number should also be “Fizz” if it contains digit “3.”&lt;/p&gt;

&lt;p&gt;A number should also be “Buzz” if it contains digit “5.”&lt;/p&gt;

&lt;p&gt;A number should also be “FizzBuzz” if it contains both.&lt;/p&gt;

&lt;p&gt;– anonymous interviewer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh, no!&lt;/p&gt;

&lt;p&gt;Nobody told you there could be more…&lt;/p&gt;

&lt;p&gt;Don’t fret! We are going to go through that. Let’s add a new test for the “Fizz” part with the new requirement.&lt;/p&gt;

&lt;p&gt;We are going to generate the sequence until 32. Some numbers, which weren’t “Fizz” before, will become such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`fizz&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;just&lt;/span&gt; &lt;span class="n"&gt;contain&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt; &lt;span class="sc"&gt;'3'&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// 13 becomes Fizz&lt;/span&gt;
    &lt;span class="c1"&gt;// 23 becomes Fizz&lt;/span&gt;
    &lt;span class="c1"&gt;// 31 becomes Fizz&lt;/span&gt;
    &lt;span class="c1"&gt;// 32 becomes Fizz&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, the test is failing.&lt;/p&gt;

&lt;p&gt;To make it pass we will need to modify the function &lt;code&gt;isFizz&lt;/code&gt; appropriately. You should include the check for “it contains digit 3” on top of the original condition. In boolean logic (last time I checked) it was an “OR” operation between those two conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;number.toString().contains('3')&lt;/code&gt; part. The test is passing now. But a few of other tests are failing!&lt;/p&gt;

&lt;p&gt;Oh no!&lt;/p&gt;

&lt;p&gt;We will have to fix those tests. We should replace numbers containing digit “3” with “Fizz”:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`buzz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`fizz&lt;/span&gt; &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="nf"&gt;numbers`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hold on a second… Doesn’t this feel weird to you?&lt;/p&gt;

&lt;p&gt;Yeah, I think this last case covers all our edge cases. That is because it (kind of) includes all other tests. So you should get rid of those tests!&lt;/p&gt;

&lt;p&gt;Oh, and don’t forget to demote the private field &lt;code&gt;fizzBuzz&lt;/code&gt; back to the local variable.&lt;/p&gt;

&lt;p&gt;Here we go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Assert.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;

&lt;span class="nd"&gt;@Suppress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FunctionName"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`generating&lt;/span&gt; &lt;span class="n"&gt;fizz&lt;/span&gt; &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="nf"&gt;sequence`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// ACT&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we want to implement final two requirements.&lt;/p&gt;

&lt;p&gt;For that let’s change our test to go until &lt;code&gt;53&lt;/code&gt;, so we hit more attractive edge cases. And some of the numbers will become “Buzz” and some other numbers ought to become “FizzBuzz” now.&lt;/p&gt;

&lt;p&gt;See for yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`generating&lt;/span&gt; &lt;span class="n"&gt;fizz&lt;/span&gt; &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="nf"&gt;sequence`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// ACT&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// 35 became FizzBuzz&lt;/span&gt;
    &lt;span class="c1"&gt;// 51 became FizzBuzz&lt;/span&gt;
    &lt;span class="c1"&gt;// 52 became Buzz&lt;/span&gt;
    &lt;span class="c1"&gt;// 53 became FizzBuzz&lt;/span&gt;

    &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
    &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"41"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"44"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"46"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"47"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"49"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"FizzBuzz"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make this pass, we will need to add similar condition to the &lt;code&gt;isBuzz&lt;/code&gt; private function. Notice the &lt;code&gt;number.toString().contains('5')&lt;/code&gt; part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'5'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tests are back to green now (they pass).&lt;/p&gt;

&lt;p&gt;Don’t you notice how &lt;code&gt;isBuzz&lt;/code&gt; and &lt;code&gt;isFizz&lt;/code&gt; functions have a similar structure? Don’t you think we should be able to extract that structure?&lt;/p&gt;

&lt;p&gt;Let’s do it!&lt;/p&gt;

&lt;p&gt;First, we will extract &lt;code&gt;dividesBy(number, divider)&lt;/code&gt; private function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'5'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;divider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="n"&gt;divider&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second, we will extract &lt;code&gt;containsDigit(number, digit)&lt;/code&gt; private function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;containsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;containsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;containsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how &lt;code&gt;digit&lt;/code&gt; here is not a character or string. It is an integer.&lt;/p&gt;

&lt;p&gt;That way, we should be able to extract the whole structure (&lt;code&gt;dividesBy&lt;/code&gt; or &lt;code&gt;containsDigit&lt;/code&gt;) out of those two functions.&lt;/p&gt;

&lt;p&gt;Here we go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesOrContainsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesOrContainsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;dividesOrContainsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;containsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your interviewer is not stopping your refactoring yet. So maybe he is out of requirements?&lt;/p&gt;

&lt;p&gt;Thank goodness!&lt;/p&gt;

&lt;p&gt;Finally, you can do that magic strings extraction refactoring! For that, we will extract “Fizz” and “Buzz” strings out of respective edge cases. And from the “fizzbuzzy” one too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;FIZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;BUZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;FIZZ_BUZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"$FIZZ$BUZZ"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So why are we extracting these magic strings, anyway?&lt;/p&gt;

&lt;p&gt;You might ask that yourself…&lt;/p&gt;

&lt;p&gt;Or is it just the interviewer asking you that question?&lt;/p&gt;

&lt;p&gt;Probably, because you want to make it easy to change one of these strings in just one place, don’t you?&lt;/p&gt;

&lt;p&gt;And that is where the thought strikes you! What if I need to change “Fizz” to “Fizzy”?&lt;/p&gt;

&lt;p&gt;Yep.&lt;/p&gt;

&lt;p&gt;I’ll have to fix all these occurrences in the test suite.&lt;/p&gt;

&lt;p&gt;Annoying!&lt;/p&gt;

&lt;p&gt;Let’s replace all the magic strings in the test too. We will have to promote these private constants &lt;code&gt;FIZZ&lt;/code&gt;, &lt;code&gt;BUZZ&lt;/code&gt;, and &lt;code&gt;FIZZ_BUZZ&lt;/code&gt; to internal access level so that that the test can access them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;FIZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;BUZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;FIZZ_BUZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"$FIZZ$BUZZ"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, we are going to replace the string occurrences in the test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;FizzBuzz.Companion.BUZZ&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;FizzBuzz.Companion.FIZZ&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;FizzBuzz.Companion.FIZZ_BUZZ&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Assert.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;

&lt;span class="nd"&gt;@Suppress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FunctionName"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzzTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`generating&lt;/span&gt; &lt;span class="n"&gt;fizz&lt;/span&gt; &lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="nf"&gt;sequence`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ARRANGE&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fizzBuzz&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// ACT&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sequence&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fizzBuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// ASSERT&lt;/span&gt;
        &lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"14"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"26"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"28"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"29"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"41"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"44"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s"&gt;"46"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"47"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"49"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All your tests should be green at this point.&lt;/p&gt;

&lt;p&gt;Did you need to do all these refactorings?&lt;/p&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Do you need to know how to do them, so that you are ready for any requirement change?&lt;/p&gt;

&lt;p&gt;Absolutely!&lt;/p&gt;

&lt;p&gt;Here is the final production code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FizzBuzz&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;FIZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Fizz"&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;BUZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Buzz"&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;FIZZ_BUZZ&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"$FIZZ$BUZZ"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FIZZ_BUZZ&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FIZZ&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;BUZZ&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isBuzz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="nf"&gt;dividesOrContainsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isFizz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="nf"&gt;dividesOrContainsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;dividesOrContainsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;containsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;containsDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;dividesBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;divider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="n"&gt;divider&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I genuinely thank you for reading, and I encourage you to practice your basic foundations.&lt;/p&gt;

&lt;p&gt;There are tons of different challenges for that on websites like &lt;a href="http://codingdojo.org/kata/"&gt;http://codingdojo.org/kata/&lt;/a&gt; and &lt;a href="http://kata-log.rocks"&gt;http://kata-log.rocks&lt;/a&gt;. Huge thank you to creators and maintainers!&lt;/p&gt;

&lt;p&gt;Liked this article? – Share it with your friends, on social media, hacker news, Reddit, etc. If you are interested in Kotlin, &lt;a href="https://iwillteachyoukotlin.com"&gt;check out more of my stuff on Kotlin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>beginners</category>
      <category>career</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
