<?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: Igor Spasić</title>
    <description>The latest articles on DEV Community by Igor Spasić (@igr).</description>
    <link>https://dev.to/igr</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%2F223724%2F9c637cda-c8b6-4388-9ff7-41d28b966b74.jpeg</url>
      <title>DEV Community: Igor Spasić</title>
      <link>https://dev.to/igr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/igr"/>
    <language>en</language>
    <item>
      <title>Color code</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Mon, 02 May 2022 08:41:49 +0000</pubDate>
      <link>https://dev.to/oblac/color-code-2cia</link>
      <guid>https://dev.to/oblac/color-code-2cia</guid>
      <description>&lt;p&gt;Standard programming languages are generic. While that is the purpose of such language, it leads to many ways of understanding and doing the same thing.&lt;/p&gt;

&lt;p&gt;The idea is to establish specific guides that should lead to uniquely designed code, hopefully, a better one, leaving less space for a different interpretation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why 'color'?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We need a new term for the code categorization. Common terms, 'type' or 'kind,' are already used in a different context. And it's fun!&lt;/p&gt;

&lt;p&gt;Let's begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/10-data.md"&gt;🟦 DATA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/11-builder.md"&gt;🟪 BUILDER&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/12-state.md"&gt;🟥 STATE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/13-function.md"&gt;🟨 FUNCTION&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/14-action.md"&gt;🟧 ACTION&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/15-binding.md"&gt;Binding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/16-context.md"&gt;⬛️ CONTEXT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/17-misc.md"&gt;Misc topics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/igr/color-code/blob/main/doc/20-color-wheel.md"&gt;🍭 Color wheel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Calculator - using Ctx&lt;/li&gt;
&lt;li&gt;ToDo App - simple app with two layers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/igr/color-code/blob/main/doc/32-example-restaurants.md"&gt;Restaurants&lt;/a&gt; - real-world web app with Ktor &amp;amp; Exposed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Primary colors
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🟦 == calm, unchanged, stable
🟨 == pure, light, combined
🟥 == contagious, changes other colors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚡️ Pro Tip: don't take this too serious.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>software</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Video killed the text star</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Mon, 13 Jul 2020 21:18:57 +0000</pubDate>
      <link>https://dev.to/oblac/video-killed-the-text-star-527o</link>
      <guid>https://dev.to/oblac/video-killed-the-text-star-527o</guid>
      <description>&lt;p&gt;Look here.&lt;br&gt;
There is no pause button.&lt;br&gt;
No colors. No sound.&lt;br&gt;
No animation plastic.&lt;br&gt;
There are only letters and the whole cosmos of your intelligence and imagination.&lt;br&gt;
And are you ready to replace video with stimulation?&lt;/p&gt;

&lt;h2&gt;
  
  
  Pictures Came And Broke Your Heart
&lt;/h2&gt;

&lt;p&gt;7 minutes of video to get to one CLI command. 23 minutes to run the Hello World example. 45 minutes of video to learn about three novelties of some new concept. But also 300 minutes of video, and I still don't understand the concept I'm studying.&lt;/p&gt;

&lt;p&gt;According to one study, YouTube is a favorite platform for acquiring knowledge among the younger population (up to 23 years). This coincides with my observation; through recent conversations with younger software engineers, I’ve noticed a recurring answer: watching video tutorials as the primary source of additional knowledge (one that is not acquired in the workplace).&lt;/p&gt;

&lt;p&gt;This state of affairs can be viewed in two ways. One is attributing the results to evolution. Everything (the world) is changing rapidly: we no longer listen to records, but stream songs. Take it or leave it, the demand for survival is inevitable: you press the &lt;code&gt;play&lt;/code&gt; button or are labeled as a victim of the digital generation gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rewritten By Machine On New Technology
&lt;/h2&gt;

&lt;p&gt;Reading is active. Watching is passive.&lt;/p&gt;

&lt;p&gt;Research confirms this, it's no secret: watching video content does not drive cognitive processes in the way that reading does. Further research on this topic indicates that the adoption of the content is more complete if it is in the form of a text.&lt;/p&gt;

&lt;p&gt;However, the research I have come to is not complete; the mentioned advantages are not so drastic that we could irrefutably press "stop" on the video and exclude it from the equation forever. The video has its powers: it can be more efficient and more convenient to use.&lt;/p&gt;

&lt;p&gt;In fact, it is not a problem in education with video content. The problem is when it becomes the &lt;em&gt;only&lt;/em&gt; and/or &lt;em&gt;primary&lt;/em&gt; source of learning. Then we are not talking about evolution, but &lt;em&gt;degradation&lt;/em&gt;. Man is not evolving at the speed of technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  I Heard You On The Wireless Back In Fifty Two
&lt;/h2&gt;

&lt;p&gt;Things are drastic in the field of software engineering. Prone to technology, we rely on it pretty lightly. As typing code is just a &lt;em&gt;skill&lt;/em&gt;, learning by watching only becomes meaninglessly inefficient.&lt;/p&gt;

&lt;p&gt;The ease of generating video content does not make the situation any easier. Mixed with the need for attention and natural propensity to talk, inefficient content is multiplied by geometric progression and actually &lt;em&gt;slows&lt;/em&gt; the learning down.&lt;/p&gt;

&lt;p&gt;Why do I find video content (mostly) inappropriate for the education of software engineers? If we expose the problem: code is text. The code is understood by reading. A video that retells the text adds an extra layer to the learning process. Instead of dealing with an active understanding of the source, we are dealing with a passive understanding of the narrative.&lt;/p&gt;

&lt;p&gt;In other words, the essence of the video can often be presented in simple, short text. It can be understood in a significantly shorter time than some video could.&lt;/p&gt;

&lt;p&gt;The same goes for presentations - they are nothing more than live video. I have gone through hundreds of software presentations and I’ve noticed the same pattern: inefficiency of knowledge transfer. But more on that another time.&lt;/p&gt;

&lt;p&gt;This doesn’t mean that every text is good. But the text medium has one wonderful feature, which video content doesn’t have. I call it "scanning"; I don't know if there is an official name for it. The exercise makes it easy to, by scanning the text, quickly - really quickly - get information about whether it makes sense, whether it offers a solution to a specific problem, and whether it is worth consuming further. Only then can one get to a more careful reading of the content.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Can’t Rewind We’ve Gone Too Far
&lt;/h2&gt;

&lt;p&gt;I would not like to ring all the bells and shout that it’s high time, but the situation is threatening to get out of control. In the desire to become efficient, we have allowed the technology to obscure our goal and, thus, slow us down.&lt;/p&gt;

&lt;p&gt;If we go a bit further: we’re becoming lazy. Are we not?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I met your children&lt;br&gt;
What did you tell them?&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>learning</category>
    </item>
    <item>
      <title>Stray Of (Software) Development</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Wed, 08 Jul 2020 13:03:22 +0000</pubDate>
      <link>https://dev.to/oblac/stray-of-software-development-m87</link>
      <guid>https://dev.to/oblac/stray-of-software-development-m87</guid>
      <description>&lt;p&gt;It’s been itching me for a long time now, I fail to resolve the feeling that not everything is as it should be; deceived by the noble reflection of the guilds. Finally, many years later, the feeling becomes a thought, and the words find their way.&lt;/p&gt;

&lt;p&gt;Software development is chained, it doesn’t go much further; and that is caused by one thing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Modern software development makes simple tasks difficult, in order to make trivial ones even easier.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Twenty years of almost daily typing of code are woven into this thought. It should not be dismissed lightly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Start?
&lt;/h2&gt;

&lt;p&gt;The programming languages we mostly use are still general in purpose. Each for itself is a ‘language for all’, reaching the exaggerated-to-nonsense concepts of OOP at best. Programming languages know how to require unnatural, too extensive precision in order to, for example, define a variable type, and are easily lost in the more demanding intention of controlling the code. There are only compile-time and run-time phases (phase distinction), imposed by the method of obtaining executable code, not by necessity. We are still struggling to separate exceptions from mistakes. We scare beginners with patterns, and we stopped writing algorithms. What we learn has not changed for decades, it’s just got a new syntax.&lt;/p&gt;

&lt;p&gt;What would be the evolution of programming languages? The end of their existence. Generalization is generalizing, unification of actors, reduction of diversity and characteristics. We need new, domain languages, each of which solves specific problems and can be mixed. We need languages that we can write and refine ourselves, change grammar and syntax on the go. We need languages that have solved memory management, synchronization, and everything that influences the abstraction of the domain being modeled: as great deviation from machine thinking as possible.&lt;/p&gt;

&lt;p&gt;And the frameworks! Everything that we fail with programming languages, we solve through programming libraries. Frameworks are actually platforms: you do not program in a framework, but in a platform, from which there is no way out once adopted. The framework should only provide a… framework in which the programmer keeps solving trivial things as he pleases; the platform gives you a solution to trivial things, but also molds in how you do everything else. Do we need magic to bind backhand components? Do we need a magical frontend that recognizes all the changes on its own? The correct framework limits the use to the solutions it offers, thus, by design, not allowing the developer to misuse it. Imagine such an API that explains itself, where the framework takes you with its syntax to the next step, not StackOverflow! The platform design is determined by the same sluggishness that demands to be solved as soon as possible and move on, or by undercooked concepts that do not solve the cause, but the consequence. Corporations can play because they have followers, thus allowing incremental tectonic changes to their platforms. To mutually cooperate, that they don’t know. Software platforms are becoming a means of consumerism, turning developers into consumers, and attracting new ones with colorful royalties of easy solution to the trivial.&lt;/p&gt;

&lt;p&gt;The world of programming is experiencing a crisis of hyperproduction. A way to attract a programmer is to impose compulsive needs on him. And those needs must be homogeneous, not individual. Ergo, we do not solve difficult tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inherence?
&lt;/h2&gt;

&lt;p&gt;There’s that urban programming proverb that says a good programmer is a lazy programmer. He hates doing repetitive work, thus finding a way to program them instead.&lt;/p&gt;

&lt;p&gt;I accepted it for a long time, until recently - I learned that it’s not quite like that. Although the proposition is in place, it turns out that the lazy programmer is also lazy to program the solution. At least that’s my experience - I admit, I’ve done it countless times myself. A barely sufficient solution is as dangerous as a pre-engineered one.&lt;/p&gt;

&lt;p&gt;The right approach should be different: laziness shouldn’t be the one indicating refactoring, but analysis. And it is just the opposite of laziness; it requires the active involvement of cognitive skills and knowledge.&lt;/p&gt;

&lt;p&gt;The topic here is not laziness, but attitude. I don’t want programming code to be determined by feeling, but by thinking. I don’t want software development to be determined by solutions to trivial tasks, but by the progression of ideas for solving difficult ones.&lt;/p&gt;

&lt;p&gt;In the end, I have to ask myself: is the situation like this because it’s enough for us?&lt;/p&gt;

&lt;p&gt;Because then we’re in trouble. And if it’s still OK for you… then nothing.&lt;/p&gt;

</description>
      <category>development</category>
    </item>
    <item>
      <title>DFE FTW!</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Mon, 06 Jul 2020 16:33:09 +0000</pubDate>
      <link>https://dev.to/oblac/dfe-ftw-3dfj</link>
      <guid>https://dev.to/oblac/dfe-ftw-3dfj</guid>
      <description>&lt;p&gt;The blooming world of software development seems to be fanatically obsessed with efficiency and rapid production; until someone, as in that fairy tale, shouts “The king is naked” and points out the excess of talking, and the lack of results. In this regard, there is one important practice that is, as far as I can see, poorly cared for: &lt;code&gt;DFE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is not something that is taught in agile courses. It’s not a glamorous topic to write about. This practice is assumed and almost always neglected. And it all costs money, and it all erodes (your) project day by day.&lt;/p&gt;

&lt;p&gt;DFE is an acronym for Developer-First Experience, defined as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is the duty of project managers to remove any doubts that a developer encounters during their work. The project should be set up exclusively to suit the developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Doubts
&lt;/h2&gt;

&lt;p&gt;Every time a programmer interrupts his flow to do something that is not programming is, in essence, a double waste of time: both his and the project’s.&lt;/p&gt;

&lt;p&gt;This is a specific communication problem. In addition to the code, the project environment itself serves as a means of communication between team members. We all agree that the code needs to be maintained, refactored; and in the same way one should constantly work on the project environment.&lt;/p&gt;

&lt;p&gt;What does this mean in practice? A lot of things. The project must be able to open in any programming environment (IDE) immediately after download. It is similar with starting a project - the default settings must be set for local development. All necessary services must be started with a single script, the name of which indicates what it does. There is no run.sh. There is no ‘out of the blue’ configuration that needs to be added to make everything work locally. Delete the README.md; are you handling it now?&lt;/p&gt;

&lt;p&gt;Next: all logs, errors, reports, documentation, and settings must be clearly available in one and only one place, within the project. The CI/CD must set the results clearly and regularly to be accessed in an identical way, regardless of the service. Automation does not stop with a successful project build.&lt;/p&gt;

&lt;p&gt;Next: there must be access to every part of the system in the working and test environment (i.e. dev/test environment). Everyone must be able to repeat any scenario and hook up to a service on any port. The application must have an admin console that provides quick information (system status, ssh access, variables, etc.). Setting up a new version of the service must be one-step, which - I can’t stress this strongly enough - must take as little time as possible.&lt;/p&gt;

&lt;p&gt;And the code: it must be rich in information, not only in the source (already so much talked about), but also in the runtime (less talked about). Proper logging, input verification, unambiguous error location… pragmatic detail is not a flaw.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dellusion
&lt;/h2&gt;

&lt;p&gt;Many will say they already have all this. What I am writing about may even seem trivial. But, alas, it’s not.&lt;/p&gt;

&lt;p&gt;A project set up in such a way that it leaves no doubts, idleness, unnecessary waiting… I have not had the opportunity to meet often. Usually everything ends with some README.md or wiki, in a clinch between the need to keep everything simple and, on the other hand, the need for detailed and comprehensive documentation. Good luck with that! Sometimes there is an intention for everything to be as it should be, which ends with the initial setup. Thereafter, no one is dealing with the project anymore, or, even worse, everyone is dealing with it, and the information is being patched or shared through the wrong channels.&lt;/p&gt;

&lt;p&gt;To repeat the idea from the introduction: fixed on the solutions from the neighbouring yard, we leave our own garden unweeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  DFE!
&lt;/h2&gt;

&lt;p&gt;Litmus test is a new programmer on the project: how long it takes him to find the error on the last test, start the project locally from scratch and start coding without any consultation with the team. Does your project pass this test?&lt;/p&gt;

&lt;p&gt;DFE is something that is constantly being worked on as the project grows and becomes more complicated. Constantly! It’s good to listen to the team’s daily communication channels for topics that slow them down: every time someone asks ‘how to…’, ‘where is…’, it’s time to apply DFE.&lt;/p&gt;

&lt;p&gt;It is allowed to be creative. Where is that AI, or machine learning, that recognises cats or generate quasi-artistic content? It is welcome in my garden, there is soooo much weeding to do.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>project</category>
      <category>development</category>
    </item>
    <item>
      <title>Never forget</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Mon, 06 Jul 2020 16:24:35 +0000</pubDate>
      <link>https://dev.to/oblac/never-forget-26d8</link>
      <guid>https://dev.to/oblac/never-forget-26d8</guid>
      <description>&lt;p&gt;We code software. Every day, every hour, an endless stream of code gets written and merged into products. The human-written software codebase is massive. The Space Shuttle runs on 400 thousand lines of code. The Large Hadron Collider uses 50 million lines. And all Google services combined run on 2 billion lines of code.&lt;/p&gt;

&lt;p&gt;Software runs technology. Technology has become omnipresent in our lives; from pocket devices to augmented reality and artificial intelligence. The impact that technology is making on human lives is undeniable and inevitable. This fact has its burden: is the technology growing in the right direction?&lt;/p&gt;

&lt;p&gt;The answer to that question echoes from the past: it can be found in the thoughts of the first computer engineers and among the ideas of the first technology visionaries. They all promote the very same message: the purpose of technology is not about having everyone interacting online all the time; technology is not a universal remedy (hard) to swallow.&lt;/p&gt;

&lt;p&gt;Technology is the challenge for humankind to evolve. It is an opportunity to dramatically increase the collective knowledge, to address the most challenging problems. It is a call to action for public and private sectors to recognize the exponential growth of humankind's challenges, and to provide the vigorous, proactive, strategic pursuit of meaningful evolution.&lt;/p&gt;

&lt;p&gt;We, the developers, are makers, creators. We are given the tools and the power to produce the code that will shape the future. We must come up with disruptive ideas that will lead to organisational and societal transformations. Such an attitude should be part of the DNA of any software company that shapes products, services and work. We are here not to code, but to answer the challenges.&lt;/p&gt;

&lt;p&gt;Hello world. Never forget to keep evolving.&lt;/p&gt;

</description>
      <category>technology</category>
    </item>
    <item>
      <title>Who’s Suffering From Cobol?</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Wed, 13 May 2020 10:19:07 +0000</pubDate>
      <link>https://dev.to/oblac/who-s-suffering-from-cobol-4oed</link>
      <guid>https://dev.to/oblac/who-s-suffering-from-cobol-4oed</guid>
      <description>&lt;p&gt;These days, there’s been an urgent demand for COBOL programmers across a number of US states. As we’re talking about a programming language designed in the late 50s, i.e. some 60 years ago, this demand is quite a precedent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why COBOL?
&lt;/h2&gt;

&lt;p&gt;Let’s start at the top. COBOL is a programming language used on mainframe computers in the 60s. Business systems such as banks or public administration systems primarily used it. These computer systems, some of which date back to the 70s, are still in use. According to a &lt;a href="http://fingfx.thomsonreuters.com/gfx/rngs/USA-BANKS-COBOL/010040KH18J/index.html"&gt;2017 Reuters report&lt;/a&gt;, over 40% of US banks still use systems built on COBOL. Over 80% of in-person transactions use COBOL, and 95% of ATMs rely on COBOL code. We’re talking about &lt;em&gt;220 billion&lt;/em&gt; lines of COBOL code that are still in use—in the US alone.&lt;/p&gt;

&lt;p&gt;COBOL was designed a couple of years after FORTRAN, the language used mainly by engineers. These two languages have a lot in common (which is also a sort of window into that early age of software development). The idea itself behind COBOL was fine. It was to create a standardised business computer language for a wide range of computers; i.e. a portable programming language for data processing. That’s where its name derives from — &lt;code&gt;COmputer Business Oriented Language&lt;/code&gt;. The language was designed by representatives from corporations, as well as the US Department of Defense. It was conceived as a temporary solution, as a sort of a stopgap. However, the Defense Department passive-aggressively forced computer manufacturers to provide support for COBOL. They’d refuse to rent or buy any system without a COBOL compiler, unless it could be proven that COBOL was somehow disrupting system performance. In only a year, COBOL set off on a journey to meet its destiny. It became the industry standard and quite possibly the most used programming language of all time.&lt;/p&gt;

&lt;p&gt;Shortly after, COBOL got its first upgrades, such as the ability to create reports. This made the language even more popular. In the late 60s, ANSI created the first COBOL standard. Since then, the standard has been revised and amended a couple of times, roughly every ten years. The last revision was in 2014, so in fact not so long ago. COBOL is one of the first high-level computer languages. The programme is written in a code that looks more like spoken (English) language than machine commands. At the time of its conception, this was both novel and valuable. COBOL also has robust support for data processing, built into the language itself. This way, COBOL replaced a large amount of data handling, which at that time had to be done manually. Mainframe computer manufacturers promoted the language, with IBM at the forefront. To this day, the company has been producing new versions of mainframe solutions. This helped COBOL become an integral part of numerous computer systems in later decades, some of which perform vital business or government functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  COBOL as programming language
&lt;/h2&gt;

&lt;p&gt;COBOL is a simple programming language. Its simplicity is what keeps all those billions of lines of code working; making it clear, and I dare say, more resilient to mishaps. Let me be clear: people make mistakes in COBOL as much as in the next modern programming language. But the lack of complex concepts makes the language more resilient. And so it is easier to understand and maintain it. As COBOL evolved, it started including more complex concepts. For example, it got its object-oriented features in the 2002 version.&lt;/p&gt;

&lt;p&gt;From today’s perspective, programs written in COBOL look crude, even painful at times. The syntax is very "talkative", the documentation is incomplete. It’s far from being cool, in fact, COBOL’s popularity over the past 20 or so years has been pretty low. It remains the language of mainframe computers. It’s tucked under the heap of modern computer languages and solutions that have overwhelmed us throughout the years. Software development has moved to the web and cloud. Processors are far more powerful than before. All this calls for new concepts and brings about different programming languages.&lt;/p&gt;

&lt;p&gt;As a programming language, COBOL lives on. While it didn’t exist as an open code software back in the 80s and 90s, things have changed. Today there’s a GNU version of the compiler. You can find environments and add-ons for COBOL development in all operational systems. There are online communities that still nurture the skills of coding using COBOL.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with 200 billions lines of COBOL code?
&lt;/h2&gt;

&lt;p&gt;This is the question that’s troubling the US business world.&lt;/p&gt;

&lt;p&gt;Let’s take a step back first. The awareness of using legacy solutions certainly exists. 92 out of 100 best US banks still use mainframe computers. 70% of these banks are Fortune 500 companies. If we accepted that COBOL has become a remnant of the past and mainframe computers should give way to smaller servers and cloud computers, how come this hasn’t been the case?&lt;/p&gt;

&lt;p&gt;Interestingly, there’s a body in the US that evaluates system reliability. It's called the Government Accountability Office. The GAO has reported systems owned by the state in a desperate need of a thorough update. For example, the Department of Education still uses a 1973 system to process student data. It’s maintained by 18 contractors and requires special hardware, so it’s hard to integrate with modern software. The GAO considers COBOL a legacy programming language. And that reflects the concurrent issue of finding and hiring new programmers. This deficit in the workforce has made COBOL specialists extremely expensive.&lt;/p&gt;

&lt;p&gt;Now, let’s go back to the question: why don’t we abandon COBOL and migrate to new, modern computer systems and solutions?&lt;/p&gt;

&lt;p&gt;Because it would cost us dearly. Let me emphasize that: it’s ridiculously expensive. The Commonwealth Bank of Australia replaced their COBOL platform in 2012. It took them five years and the whole endeavour cost $750 million. There’s another example where migration of a similar system to a Java platform lasted four years and still hasn’t been completed.&lt;/p&gt;

&lt;p&gt;So the conclusion is self-evident: migration from a legacy platform is neither trivial nor cheap. While the business world might be able to afford it, many public institutions (in the US) simply can’t afford it.&lt;/p&gt;

&lt;p&gt;The Homeland Security Department, for instance, uses a 2008 IBM z10 mainframe system which runs on COBOL-powered programmes. The Social Security Administration uses some 60 million lines of COBOL code. It’s similar to computer systems of other state institutions across the US—some of them rely on systems that are over 40 years old.&lt;/p&gt;

&lt;p&gt;As it would seem, COBOL is here to stay at least for quite some more time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why now?
&lt;/h2&gt;

&lt;p&gt;At times of crisis, the amount of data that needs processing is significantly increased. For example, due to an increasing number of people losing their jobs, the number of applications for unemployment in New Jersey soared by 1600%, with 580 thousand people filing claims in a short amount of time.&lt;/p&gt;

&lt;p&gt;Legacy systems simply can’t support this change in traffic. No system can—unless it was designed from the get-go to be able to support this. On the other hand, designing robust systems is in itself a complex feat. Thus, their development takes more time and costs more. Unfortunately, in a world where we want everything done right away, software development quality isn’t picking up. But that’s a topic that deserves a blog post of its own.&lt;/p&gt;

&lt;p&gt;All of this requires that in extraordinary circumstances, existing systems be maintained: monitored, repaired, or sped up. The lack of programmers has led to a public outcry for COBOL programmers from users affected by increased traffic, primarily state institutions. Online COBOL courses have recently started to spring up; with IBM at the forefront, obviously looking to increase its user base.&lt;/p&gt;

&lt;p&gt;The last time that COBOL was popular was at the turn of 2000, due to the so-called Y2K problem. The industry had time to prepare for those events as it had been working on that transition since the 80s. In case of crises, such as the COVID-19 pandemic, there was no time to prepare.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can we take away from this?
&lt;/h2&gt;

&lt;p&gt;What we can do is learn something from this.&lt;/p&gt;

&lt;p&gt;We, programmers, have been obsessed with shiny objects of software novelties. "Programmers are like children", I was once told by a CTO of a Singapore bank. "They run around like crazy — look at this, look at that, drawn to tech novelties, but they easily bruise in the process and break things", he added, answering my question on adopting new technologies in their banking system. And he wasn’t wrong. The industry doesn’t care whether your code is written this or that way. It cares whether your code will continue to work in 20 years and whether someone will understand it. It is, after all, the industry that gives value to the biggest part of code. For example, Java is the new COBOL—and I’ll admit this only once—Oracle does a great job of maintaining compatibility with older versions and is super cautious when introducing novelties. I’m the first one to badmouth Java whenever I get the chance and call it the dullest modern language in the world, but it’s the (dull) coder in me who's speaking, not the engineer.&lt;/p&gt;

&lt;p&gt;That’s why we need to be careful — &lt;em&gt;very careful&lt;/em&gt; — with technologies that we adopt and that are becoming the norm. I’m not sure whether the organic approach is the right one: when we adopt a thing for the sake of its popularity. Take Python for instance. Imagine just how much it would cost the industry to migrate all the programmes from version 2 to version 3 if they chose to use Python as the language of their computer systems. Or AngularJS, a failed concept that was later jettisoned. That’s why I repeat, we need to be careful with what we adopt. Sometimes more isn’t better.&lt;/p&gt;

&lt;p&gt;There’s one more thing we can learn from this and it concerns our everyday work. If nothing else, then at least we, who develop software, must not forget two equally important values of each computer system—robustness and sustainability. &lt;strong&gt;Write the code that outlives you&lt;/strong&gt;. On the other hand, robustness and quality are something we need to invest into. "Haste makes waste", as wise COBOL programmers would say.&lt;/p&gt;

&lt;h2&gt;
  
  
  BONUS: COBOL in practice
&lt;/h2&gt;

&lt;p&gt;GNU Cobol is easily installed on OSX: &lt;code&gt;brew install gnu-cobol&lt;/code&gt;. You can use Sublime or VS Code as the editor, both of these support COBOL; for the latter, it’s more advanced than simple recognition of the syntax.&lt;/p&gt;

&lt;p&gt;That’s it, now prepare to feel old.&lt;/p&gt;

&lt;p&gt;Let’s have a look at a COBOL programme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        IDENTIFICATION DIVISION.
        PROGRAM-ID. HELLO.
        DATA DIVISION.
          WORKING-STORAGE SECTION.
          *&amp;gt; 9 — numeric A — alphabetic X — alphanumeric V — decimal S — sign
          01 NUM-VAR PIC S9(3)V9(2).
          01 COUNT1 PIC 9(2) VALUE 0.
          01 NUM PIC 9(9).
          01 TEXT-VAR PIC X(8) VALUE 'OBLAC.RS'.
          01 STR1 PIC X(8).
          01 STR2 PIC X(8).
          01 GROUP-VAR.
            05 BROJ PIC 9(3) VALUE 173.
            05 NAZIV PIC X(15) VALUE 'LALALAND'.
          01 CHECK-VAL PIC 9(9).
            88 PASS VALUES ARE 044 THRU 100.
            88 FAIL VALUES ARE 000 THRU 43.
        PROCEDURE DIVISION.
          DISPLAY 'CIAO COBOL'.
          MOVE 2.1 TO NUM-VAR.
          DISPLAY "NUM VAR : "NUM-VAR.
          DISPLAY "TEXT VAR : "TEXT-VAR.
          DISPLAY "GROUP VAR : "GROUP-VAR.
          COMPUTE NUM = (NUM-VAR * NUM-VAR).
          DISPLAY "MUL : "NUM.

          IF NUM &amp;gt; 3 AND NUM LESS THAN 100 THEN
            DISPLAY "Yes!"
          END-IF

          MOVE NUM TO CHECK-VAL
          IF FAIL
            DISPLAY "Oops"
          END-IF

          INSPECT TEXT-VAR TALLYING COUNT1 FOR CHARACTERS.
          DISPLAY "Broji : "COUNT1.
          INSPECT TEXT-VAR REPLACING ALL 'C' BY 'K'.
          UNSTRING TEXT-VAR DELIMITED BY '.'
            INTO STR1, STR2
          END-UNSTRING.
          DISPLAY STR1

          PERFORM FN WITH TEST AFTER UNTIL COUNT1=0.
        STOP RUN.

        FN.
          DISPLAY 'Hi!'.
          SUBTRACT 1 FROM COUNT1.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First of all, this is no mistake—the first columns in the programme are reserved and not used when writing code. The seventh column is also special. The code is written from the eighth column. Everything is written in capital letters, so Capslock will come in handy. :)&lt;/p&gt;

&lt;p&gt;COBOL programme is divided into &lt;code&gt;DIVISION&lt;/code&gt;s. In the first one, we declare the variables. There are no predefined types, but rather data types are defined when declaring them. You might also find group variables interesting (they look like structures), as well as some kind of &lt;code&gt;enum&lt;/code&gt; variable (&lt;code&gt;CHECK_VAL&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The programme is written in the procedural part. The programme above executes some basic computing actions and tasks. Working with strings can be particularly tedious; there’s a lot you need to write to carry out simple manipulations. The last thing you can see in our programme is how a procedure is called several times, in a loop.&lt;/p&gt;

&lt;p&gt;What COBOL was made to do is data processing, which means working with files. The language has built-in capabilities to work with files and records. Here’s what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       IDENTIFICATION DIVISION.
       PROGRAM-ID. FILES.

       ENVIRONMENT DIVISION.
         INPUT-OUTPUT SECTION.
           FILE-CONTROL.
             SELECT ZAPISI ASSIGN TO 'file.txt'
             ORGANIZATION IS SEQUENTIAL.

       DATA DIVISION.
         FILE SECTION.
           FD ZAPISI.
           01 ZAPISI-STRUCT.
             02 UID PIC 9(6).
             02 NOTE PIC X(30).
             02 ACCOUNT.
               03 AMOUNT PIC 9(6)V9(2).
               03 BALANCE PIC 9(6)V9(2).
             02 ACCOUNT-ID PIC 9(7).
             02 ACCOUNT-OWNER PIC A(50).

         WORKING-STORAGE SECTION.
           01 ZAPISI-RECORD.
             02 UID PIC 9(6) VALUE 123456.
             02 NOTE PIC X(30) VALUE 'TESTING'.
             02 ACCOUNT.
               03 AMOUNT PIC 9(6)V9(2) VALUE 000173.98.
               03 BALANCE PIC 9(6)V9(2) VALUE 000173.12.
             02 ACCOUNT-ID PIC 9(7).
             02 ACCOUNT-OWNER PIC A(50).

       PROCEDURE DIVISION.
         DISPLAY 'WRITING RECORD: 'ZAPISI-RECORD.
         OPEN OUTPUT ZAPISI
           WRITE ZAPISI-STRUCT FROM ZAPISI-RECORD
         CLOSE ZAPISI

       STOP RUN.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The programme above writes content into a file. The files you are working with here are simple, structured textual files; when you open them, I guarantee you’ll get the 80s vibe (if you’re old enough to remember them).&lt;/p&gt;

&lt;p&gt;The programmes above are compiled with &lt;code&gt;cobc -x &amp;lt;name&amp;gt;.cob&lt;/code&gt; which gives you the executable programme.&lt;/p&gt;

</description>
      <category>cobol</category>
      <category>technology</category>
    </item>
    <item>
      <title>Don't teach kids programming</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Thu, 07 May 2020 19:33:55 +0000</pubDate>
      <link>https://dev.to/oblac/don-t-teach-kids-programming-36n5</link>
      <guid>https://dev.to/oblac/don-t-teach-kids-programming-36n5</guid>
      <description>&lt;p&gt;Programming is increasingly being introduced to primary schools. This is an initiative that is recognized all around the world - many kids are being taught programming.&lt;/p&gt;

&lt;p&gt;Stop! We're wrong! Do not teach children programming!&lt;/p&gt;

&lt;p&gt;The assumption is wrong. What we are doing is observing the present and noticing the rising trend of the need for developers. We extrapolate this fact and base the future on it, assuming that the same rules will apply in 10 or 20 years from now, at the time our children become old enough to work.&lt;/p&gt;

&lt;p&gt;If there is something we do not know, it is what the future holds for the world. The dynamics of change in the digital industry are so extensive that there is no pattern which can be applied to them. The amount of information is multiplying; requirements change faster than ever. The truth is that we have no idea what the world will look like in 20 years. In such an environment, programming is, unfortunately, not a "joker" wildcard that will give our heirs a chance to master the world of the future.&lt;/p&gt;

&lt;p&gt;Moreover, the type of programming the IT market is looking for is mercilessly monotonous and stumbling. It is all about the skill; programming today has been reduced to being more about the framework timing, and less about the science. Do we really want to involve children in such an anaemic world of programming?&lt;/p&gt;

&lt;p&gt;Programming should not have a meaning in itself. Programming should be a tool - in fact, only one of the tools that will be available to people. The technical knowledge which we boast of and so passionately wish to put into young brains should not be taken as the primary source of knowledge.&lt;/p&gt;

&lt;p&gt;Instead, we need to teach children critical thinking. In a world without censorship, but with fake news, a critical attitude is more important than programming patterns.&lt;/p&gt;

&lt;p&gt;We need to teach children communication. A world in which everyone has a voice and an opinion about everything requires precise and clear communication skills and the ability to exchange ideas and thoughts.&lt;/p&gt;

&lt;p&gt;We have to teach children to work together. In a world where there are more screens than people, cooperation becomes a necessary ingredient of progress.&lt;/p&gt;

&lt;p&gt;And finally, we have to teach children creativity. Creativity is a part of what it means to be human. Creativity is something we need to constantly stimulate, now more than ever before, because that is the only way our children will discover how the world of tomorrow will function. Do not teach children programming. Teach them that they can and should change the present - that is going to be our future.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>kids</category>
      <category>technology</category>
    </item>
    <item>
      <title>TDD bowling and uncle Bob</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Wed, 06 May 2020 13:52:42 +0000</pubDate>
      <link>https://dev.to/oblac/tdd-bowling-and-uncle-bob-583m</link>
      <guid>https://dev.to/oblac/tdd-bowling-and-uncle-bob-583m</guid>
      <description>&lt;p&gt;There is one TDD kata that particularly grabs my attention. I often have a problem with it in my workshops. And some with uncle Bob, as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  TDD
&lt;/h2&gt;

&lt;p&gt;Let's first quickly agree on what TDD is all about. If you think it is about testing, you are mistaken.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TDD is about incremental development through small steps. Hence: the software design.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The idea is to develop just what is needed, incrementally. With tiny baby steps, we can reach a goal more safely without fear of overdoing it. Developing higher complexity than needed (over-engineering) is a common problem during development, and it is a natural consequence of every problem-solving process.&lt;/p&gt;

&lt;p&gt;Tests are just a tool. The same goes for refactoring, which is an integral part of one TDD cycle. Refactoring is even more important; I'll write about it next time.&lt;/p&gt;

&lt;p&gt;Moving on: every bit of development with TDD is either refactoring or adding single functionality. The test helps to determine the next (small) step or to secure a code change. First, we write the most straightforward code we can think of - it turns out that this is often a problem. The point of practicing TDD katas is also to practice this step. Once tests are passing, we must go back and refactor the initial code: the first version may be of any quality as long as it satisfies the tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's go bowling
&lt;/h2&gt;

&lt;p&gt;A typical TDD kata is the calculation of bowling scores. &lt;a href="https://oblac.rs/tdd-kuglanje-i-teca-bob/Bowling_Game_Kata.pdf"&gt;Following the example of Bob's course&lt;/a&gt; in my workshops, I first let attendees model the problem in a "standard" way. In a matter of minutes, we come out with a rich class diagram. Next, we start tackling the kata in a TDD way. The idea is to point out a simpler solution that does not require additional classes and is (relatively) easily achievable by TDD practice.&lt;/p&gt;

&lt;p&gt;The kata is described in detail in the enclosed PDF. In short, the player plays 10 times - frames. A player rolls the ball twice during each frame. The score is equal to the number of knocked pins. If a player gets all the pins in the first roll (a strike), the frame ends. Strike roll has a score bonus: the sum of knocked pins of the next two rolls. If a player knocks all pins down within two rolls (spare), the bonus is a number of knocked pins of the next roll.&lt;/p&gt;

&lt;p&gt;Write a &lt;code&gt;Game&lt;/code&gt; class that has two methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;roll(pins)&lt;/code&gt; called every time a player throws a ball,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;score()&lt;/code&gt; called at the end of the game and returns the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's exercise this kata together. Today, let it be in Scala.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come on, Eileen, too rye aye, code in
&lt;/h2&gt;

&lt;p&gt;(I am accelerating the pace to make the article shorter)&lt;/p&gt;

&lt;p&gt;We start with minimal functionality: when a player misses everything, the game score is 0. When he knocks down only one pin, the score is 1.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Game&lt;/code&gt; class after first steps is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameX&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pins&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;roll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pins&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Unit&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="py"&gt;pins&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;pins&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;if&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="py"&gt;pins&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&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="mi"&gt;1&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="mi"&gt;0&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;Off-topic: while practicing the TDD, I have noticed various complexity-growing patterns. For example, one pattern is to allow two repetitions, while a third repetition indicates the need for generalization. &lt;code&gt;if&lt;/code&gt; block may turn into a loop, or move into the loop. Interestingly, I did not find much literature on such patterns of growing code complexity. If someone is interested in this subject, let me know.&lt;/p&gt;

&lt;p&gt;Back to the problem: we have a case of two repetitions - there are two &lt;code&gt;if&lt;/code&gt; blocks (the second one is implicit), so the code needs to be generalized. We may presume that the score for 'weak' rolls (when a player does not knock down all the pins in a frame) is equal to the number of knocked-down pins, which simplifies the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;pins&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That solved all the weak rolls. It is time to focus on cases where all pins are knocked down. Let's start with a strike (for no particular reason). If a player knocks down all pins in the first frame, and rolls a total of &lt;code&gt;7&lt;/code&gt; pins in the second frame, the score for the first frame is &lt;code&gt;10 + 7 = 17&lt;/code&gt; points. The total score after the second frame is &lt;code&gt;17 + 7 = 24&lt;/code&gt; points.&lt;/p&gt;

&lt;p&gt;We have come to a critical part, where often things go in different directions on workshops. As said, the point is to develop in baby steps. What would be the smallest change of the code that introduces the strike case (and that passes the test described above)?&lt;/p&gt;

&lt;p&gt;The first change is the introduction of history: it becomes apparent that we have to store all the rolls. The introduction of history requires refactoring of existing code. Instead of cumulatively collecting the number of knocked pins for the score, we need to preserve them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameX&lt;/span&gt; &lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;rolls&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;](&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;currentRoll&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;roll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pins&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentRoll&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pins&lt;/span&gt;
    &lt;span class="n"&gt;currentRoll&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="k"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;roll&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;score&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;Why &lt;code&gt;21&lt;/code&gt; for array size? It is merely the maximum number of rolls possible in the game of bowling.&lt;/p&gt;

&lt;p&gt;Note that we haven't introduced anything new yet. We did not design, for example, a &lt;code&gt;frame&lt;/code&gt;, that would represent the introduction of a new concept. Although we wrote much code, it was all about the refactoring to get one component back in the program, which is the history. History already existed as a concept; we just didn't preserve it: the existence of a single variable erased it. Let me emphasize this: we did not add anything new, but reclaimed the existing concept.&lt;/p&gt;

&lt;p&gt;Now we can go further: when we have history, we can calculate the bonus. This step is not refactoring now, but rather adding new functionality. The bonus depends on future rolls. Hence, we can write the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="nf"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;length&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;roll&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scoreForRoll&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;roll&lt;/span&gt;

    &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// strike&lt;/span&gt;
      &lt;span class="n"&gt;scoreForRoll&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;scoreForRoll&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;scoreForRoll&lt;/span&gt;

    &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;score&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Handling spare is similar - after adding a test, the minimal step could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="nf"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;    &lt;span class="c1"&gt;// FIX!&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;roll&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;roll&lt;/span&gt;

    &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// strike&lt;/span&gt;
      &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// spare&lt;/span&gt;
      &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;frameScore&lt;/span&gt;
    &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;score&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We've added another &lt;code&gt;if&lt;/code&gt; block to check spare. However, we need to fix the &lt;code&gt;while&lt;/code&gt; loop condition. We use the value &lt;code&gt;20&lt;/code&gt; because it is the least we can do in this step. We are aware that it is a magical value, inserted only for the test to pass, and that we are left to analyze it (read: cover with test). We don't want to address this value in the current step.&lt;/p&gt;

&lt;p&gt;The next step is examining the case of the "perfect" game: when the player consistently knocks down all the pins. The maximum score is &lt;code&gt;300&lt;/code&gt;; the above code returns &lt;code&gt;330&lt;/code&gt;, because it does not know when to stop when iterating over rolls. The conclusion is that we have to iterate the frames instead, as that's how we only know when the game is over - the number of rolls does not tell us that. Let's switch to counting frames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;  &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="nf"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;roll&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="n"&gt;roll&lt;/span&gt;

      &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// strike&lt;/span&gt;
        &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roll&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// spare&lt;/span&gt;
        &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;frameScore&lt;/span&gt;

      &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

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



&lt;p&gt;We're not done yet - the code craves for some refactoring. E.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="nf"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;playingFrame&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;simpleFrameScore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isStrike&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isSpare&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;frameScore&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;frameScore&lt;/span&gt;
    &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;score&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;playingFrame&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;isStrike&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;isSpare&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;simpleFrameScore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;rolls&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rollNdx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Nice, right? It's not all that great, though: the functions are not entirely correct. They are bound to &lt;code&gt;rollNdx&lt;/code&gt;, expecting it to be in sync with the frame. Unfortunately, there is no pure correlation (in terms of "pure functions") between a frame and roll, as the correlation depends on history. The &lt;code&gt;isSpare&lt;/code&gt; function only makes sense if a strike has already been detected, for example. All this results in functions that do not do what they are intended to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  In the meantime...
&lt;/h2&gt;

&lt;p&gt;The course Bob took is a bit different.&lt;/p&gt;

&lt;p&gt;First, it calculates the &lt;code&gt;score&lt;/code&gt; when calling &lt;code&gt;roll()&lt;/code&gt;. This approach is, of course, wrong. Bob himself reasons the same in the third test. What is a mistake? The intent of the &lt;code&gt;roll()&lt;/code&gt; function has nothing to do with the score - it serves solely to receive information about knocked pins; that's all it needs to do. Nevertheless, this erroneous approach is understandable, and I have no problem with it.&lt;/p&gt;

&lt;p&gt;What is striking (pun intended), however, is the decision to switch from iterating over rolls to iterating over frames in the same step, the third test. Sure, it is not fair to judge an example based on presentation alone. However, this premature, in no way motivated, refactoring just obstructs the idea of ​​TDD: it changes the concept without a previously apparent reason (&lt;em&gt;test&lt;/em&gt;). We came to the same conclusion in the better way I would say, a few steps later.&lt;/p&gt;

&lt;p&gt;The next concern is extracted methods such as &lt;code&gt;isSpare(int frameIndex)&lt;/code&gt;. Unlike the above example, Bob uses &lt;code&gt;rolls[frameIndex]&lt;/code&gt; in the function's code, which is particularly wrong. This term implies a clear correlation between the two values, which is not the case. The &lt;code&gt;rolls&lt;/code&gt; collection, in this example, should exclusively be read with &lt;code&gt;rollNdx&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exaggeration or not?
&lt;/h2&gt;

&lt;p&gt;Admittedly this all sounds like an exaggeration to someone: "Write the code that works now, son, don't think much". To me, these are not just little things: they accumulate and become an avalanche that comes when it is not needed. If anything, this is at least an illustration that writing a clear and clean code is not easy.&lt;/p&gt;

&lt;p&gt;Which brings us back to the beginning of the problem. The only way I can think of a code that has no challenges is to code a class diagram mentioned in the beginning. And this, somewhat, I resent Bob: his example can also be interpreted as advice that modeling (with classes) is somewhat complicated. This is not the case. Types that precisely model a domain are much more valuable than a function that uses primitive types for its calculation. What's more, Bob's approach is sort of &lt;em&gt;code smell&lt;/em&gt;, &lt;em&gt;primitive obsession&lt;/em&gt;, which I am trying to get rid of as much as possible.&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>scala</category>
    </item>
    <item>
      <title>Optimisation And Realisation</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Fri, 24 Apr 2020 19:39:12 +0000</pubDate>
      <link>https://dev.to/oblac/optimisation-and-realisation-34ia</link>
      <guid>https://dev.to/oblac/optimisation-and-realisation-34ia</guid>
      <description>&lt;p&gt;There is no developer that hasn’t heard the famous Donald Knuth quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Premature optimisation is the root of all evil.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Often this sentence is understood in the context of performance, i.e. the speed of the software execution. However, it refers more to something else.&lt;/p&gt;

&lt;p&gt;It's about the value that some code brings into the product.&lt;/p&gt;

&lt;p&gt;During the development, the programmer's goal is to write the code that effectively meets the required functionality. However, often in the desire to write a high-quality code, a programmer goes too far and introduces complexity that is greater than its real worth (over-engineering). In other words, the value of the code decreases because of the unnecessary increases in complexity. Similarly, sometimes the development focuses on features that are not critical and do not give the product essential value. Instead, development tackles less relevant features.&lt;/p&gt;

&lt;p&gt;In this context, premature optimisation is all the work that was not spent on the production of real value. The alternative to optimisation is realisation: work that actually brings value. Now the Knuth sentence is more meaningful.&lt;/p&gt;

&lt;p&gt;Striking the balance between optimisation and realisation is not reserved for planning and top-level architecture. It make sense to view work on everyday code from this perspective. No matter whether it is a feature or a code block, try to determine if it is an optimisation or a realisation. If it is an optimisation, work out whether it is premature or not. Are you working on something that brings little value, or even no value, at the moment? Are you introducing unnecessary complexity? Are you adding more edge cases than actually needed?&lt;/p&gt;

&lt;p&gt;The virtue is to avoid complexity. Detect it on time by thinking about premature optimisation.&lt;/p&gt;




&lt;p&gt;More &lt;a href="https://oblac.rs/en/optimisation-and-realization/"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>development</category>
    </item>
    <item>
      <title>CODÆRT</title>
      <dc:creator>Igor Spasić</dc:creator>
      <pubDate>Fri, 06 Mar 2020 09:24:21 +0000</pubDate>
      <link>https://dev.to/oblac/codaert-495l</link>
      <guid>https://dev.to/oblac/codaert-495l</guid>
      <description>&lt;p&gt;Code that is not art, Art that is not code. What it can be?&lt;/p&gt;

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

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
public class Oblac{String $ = $ = $ = $ = $ =

  "8OABABAWADMRWHWHBHBOB#BMBDW@AOADB6ABABA" +
  "WADMRWHWHBHBOWBMAM0A@WMBQB0ANMNMOMHANB#" +
  "WMM$MM88B#                    B@WDAHA@B" +
  "AAQAQA$                         A@M0WOW" +
  "OBOBH                             BMB#B" +
  "@WDAH                             A@BAA" +
  "QAQA$       A@M0WOWOBOBHB         MB#B@" +
  "WDAHA       @BAAQAQA$0QDW         OAWHB" +
  "HBAM#       MDW#BQWWMOWAM         QM$M@" +
  "MBM$W       HB8M#BOW$BMWH         B0WBM" +
  "RW8MD       ABMMWMB@WHBQW         WMWWM" +
  "8NBDW       @AOADWMMRABWB         MNAHW" +
  "HBOW8       W#W6BMW#B6AOW         0WWMM" +
  "ABWWW       MAAB6A$W@WHWM         WBMMO" +
  "B060Q                             BAAQA" +
  "QA$A@                             M0WOW" +
  "OBOBHBM                         B#B@WDA" +
  "HA@BAAQAQA$                   A@M0WOWOB" +
  "OBHBMB#B@WDAHA@BAAQAQA$A@M0WOWOBOBHBM8N" +
  ""+""+""+""+""+""+""+""+""+""+""+""+""+"" ;


  String $$ = "WMODBA806QRN#$@H"; String $$$=
  "https://oblac.rs"; byte[]o; int dev,coder;
  public void oblac() { if(o == null) {o = $.
  getBytes ();} if(dev &amp;gt;=$.length()){return;}


  https://oblac.rs


  while(o[dev]==0x20) dev++;int c= $$.indexOf
  (o[dev++])*16;while(o[dev] == 32) dev++;c+=
  $$.indexOf(o[dev++]); c^=$$$.charAt(coder);
  if($$$.length()==++coder){ coder =0;}System
  .out.print( (char)c);oblac();}public static
  void main(String[]a){new Oblac().oblac();}}

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



&lt;p&gt;Now, save it and:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; javac Oblac.java
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; java Oblac
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>java</category>
      <category>art</category>
      <category>code</category>
    </item>
  </channel>
</rss>
