<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Egon Elbre on Medium]]></title>
        <description><![CDATA[Stories by Egon Elbre on Medium]]></description>
        <link>https://medium.com/@egonelbre?source=rss-c01f387bc9f4------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*F6Wll9z_5dhUXEj9h4VHZA.png</url>
            <title>Stories by Egon Elbre on Medium</title>
            <link>https://medium.com/@egonelbre?source=rss-c01f387bc9f4------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 04:23:54 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@egonelbre/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Building with Value: An Example]]></title>
            <link>https://medium.com/@egonelbre/building-with-value-an-example-fa6280a1aa77?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/fa6280a1aa77</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[development-process]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Tue, 04 Jun 2019 17:07:07 GMT</pubDate>
            <atom:updated>2019-07-04T21:10:08.080Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*FWtT9uqXMYHuMIn8hPxLPQ.png" /></figure><p>Previously I described a process for developing software while trying to provide as much value and create understanding as early as possible.</p><p><a href="https://medium.com/@egonelbre/building-with-value-dd16cc5f408e">Building with Value</a></p><p>How would one iteration of this process look like?</p><p><em>I’ll walk you through one iteration using the Go programming language while deliberately showing the steps more explicitly. In practice, many of these steps could be replaced by some external tools or libraries.</em></p><p>I’ll continue with the example from the previous post, an Issue Tracker.</p><p><strong><em>The Simplified Process</em></strong></p><ol><li>Structure Follows Value: find out what is the most valuable thing to implement right now.</li><li>Spiking: we create a draft of 2–4 changes.</li><li>Gradual Stiffening: build these changes incrementally,</li><li>Cleanup: observe the wholeness and try to notice any small mistakes.</li></ol><h3>Structure Follows Value</h3><p>“What provides most Value in an Issue Tracker that we can implement right now?”</p><p>We may notice the essential pieces from the language used.</p><ul><li>I need to get an overview of the <strong>issues</strong>.</li><li>I need to find information about this <strong>issue</strong>.</li><li>I don’t have good visibility on <strong>issue </strong>progress.</li></ul><p>We may also get this information from a domain expert. We also should try to understand why exactly it is important and how it fits into the rest of the system:</p><ul><li>It shows what we are doing.</li><li>It shows what we have done.</li><li>It shows what we still need to do.</li></ul><p>Issue is definitely a valuable part. Hence we must capture it in code.</p><h3>Spiking</h3><p>To ensure that we can adequately represent the complexity of an Issue, we should create a package for it. That way, we make it significant and clear. At the same time, we create a locus of attention which allows to understand and examine the feature wholly and whether it is complete.</p><p>Of course, packages are not the only way to group things — there are also classes, functions, methods, constraints, etc. What you use to represent the idea will depend on how large, detailed, or important the contained thing is.</p><p><em>It is better to start with a notch larger grouping than is needed, and it is not difficult to make it smaller. However, the reverse, moving from smaller container to larger, is usually more complicated. e.g. Going from multiple packages to a single package vs. going from a single package to multiple.</em></p><p>We’ll add our first Spike to issue/info.go:</p><pre>package issue</pre><pre>type ID int<br>type Status string</pre><pre>const (<br>    Created Status = &quot;Created&quot;<br>    Closed         = &quot;Closed&quot;<br>)</pre><pre>type Info struct {<br>    ID      ID<br>    Caption string<br>    Desc    string<br>    Status  Status<br>}</pre><p>We must have an issue.ID to identify an issue uniquely. Each issue usually has an issue.Status associated with it. We need something to bring all the attributes together like issue.Info. Keep in mind that we are sketching the code and are not committed to this structure. We are not looking perfection, but rather a global view of how things will work together.</p><p><em>Notice that I don’t use long names such as IssueStatus, IssueInfo because the package for them already contains </em><em>issue.</em></p><p>We also need some way to store and load those issues. The way we store and load them can change. Hence we should abstract this knowledge away. We create an interface issue.Manager for it. We put it into issue/manager.go:</p><pre>type Manager interface {<br>    Create(info Info) (ID, error)<br>    Load(id ID) (Info, error)<br>    Close(id ID) (error)<br>    List() (issues []Info, error)<br>}</pre><p>To get an overview of how we will use it, we write some usage code into main.go:</p><pre>package main</pre><pre>import (<br>    &quot;fmt&quot;</pre><pre>&quot;example.com/tracker/issue&quot;<br>)</pre><pre>func check(err error) { // TODO: only for draft<br>    if err != nil {<br>        panic(err)<br>    }<br>}</pre><pre>func main() {<br>    var manager issue.Manager</pre><pre>id, err := manager.Create(issue.Info{<br>        Caption: &quot;Hello&quot;,<br>        Desc: &quot;World&quot;,<br>        Status: issue.Created,<br>    })<br>    check(err)</pre><pre>info, err := manager.Load(id)<br>    check(err)</pre><pre>fmt.Println(info)</pre><pre>infos, err := manager.List()<br>    check(err)<br>    fmt.Println(infos)<br>}</pre><p>It doesn’t matter in which order you create these pieces, and sometimes it is easier to create the usage code first, other times it is easier to create the implementation first. The thing that does matter is that both exist to ensure that we have the implementation details right and that we can integrate it with the rest of the code.</p><p>The usage code can also be sketched as a test; this depends on how the sketched code will be used, how it needs to integrate with the rest of the system and other factors.</p><h3>Gradual Stiffening</h3><p>Notice that we don’t have any runnable code yet, it’s fine, because until now we were trying to grasp what we are implementing and that all the pieces work together as intended.</p><p>Now we will step-by-step start to flesh out the actual structure, until we have a reliable and stable runnable code. We are in the beginning stages of our project, so there isn’t much to worry about. We should skim over our code and notice anything that doesn’t feel nice.</p><p>The first thing we may notice is issue.Created. What would info.Status == issue.Created mean? This suggests that we haven’t captured the intent as well as we should have. Let’s refine our sketch, info.Status == issue.Open sounds much better. Hence we change issue/info.go:</p><pre>const (<br>    Open Status = &quot;Open&quot;<br>    Done        = &quot;Done&quot;<br>)</pre><p>In main.go the manager doesn’t feel clear; it feels like a fuzzy concept without specific meaning. There probably will be more things that need to “manage” things. Is there a better name for it?</p><p>What does the manager do? “It manages and tracks issues.” Here is a clue for a nicer name Tracker. We shall refine issue/manager.go into issue/tracker.go and change:</p><pre>type Tracker interface {<br>    Create(info Info) (ID, error)<br>    Load(id ID) (Info, error)<br>    Close(id ID) (error)<br>    List() (issues []Info, error)<br>}</pre><p>We also make all the necessary adjustments to main.go. At the end of this, we should have code that compiles however, it’s okay if it is not yet completely bug-free. <em>We will do this in the next step, but gradual stiffening and cleanup are usually finished with a final cleanup pass.</em></p><h3>Cleanup</h3><p>Now we have a good idea about the feature and how to put it into code, we shall go over and fill in all the missing details and ensure that we have comments and a few tests and can use it in some form.</p><p>Here we could add an in-memory implementation of the tracker and then write some tests for it.</p><p>The other thing what we want to do here is to make it easier to understand and ensure whether the code behaves as it should. In most cases, you would wish to unit or behavior test, but they are not the only way. You could also write property tests. Or write output that could be verified by hand, if the correct behavior is difficult to describe in code.</p><p>Few interesting bits to pay attention to while solidifying code. When you come across questions, mark them as such. For example, while writing the tracker test case, I made a mistake while writing:</p><pre>tracker.Close(id)<br>// ...<br>expect := Info{<br>    ID:      id,<br>    Caption: &quot;Caption&quot;,<br>    Desc:    &quot;Desc&quot;,<br>    Status:  Closed,     <strong>// compilation error, should be Done</strong><br>}</pre><p>I mixed up two things: the method is called Close , and the resulting status is Done. Because I made a mistake while writing this, it suggests to me that the code is not clear enough, but I’m not sure how to improve it. It probably isn’t that important, so I’ll mark it as a <strong>TODO</strong> and move on to other things:</p><pre>const (<br>    // TODO: should tracker.Create renamed to &quot;Open&quot;<br>    Open = Status(&quot;Open&quot;) // Open means that issue is in progress<br>    // TODO: should &quot;Done&quot; be renamed to &quot;Closed&quot;<br>    Done = Status(&quot;Done&quot;) // Done means that issue is completed and delivered<br>)</pre><p>I could try to figure out this immediately, but I really don’t think I have the necessary information right now and I will probably find out the details while implementing other things. In a similar vein, we might reconsider Tracker method names.</p><p>Now we have captured something of value in the code. There is plenty of things we can do to improve the ease of use that code, but we have something that someone would like to use already.</p><p>Using this process helps to keep focus on what matters and at the same time bring together a bigger picture.</p><p><em>Thanks to Taavi Kivisik for review feedback.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fa6280a1aa77" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building with Value]]></title>
            <link>https://medium.com/@egonelbre/building-with-value-dd16cc5f408e?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/dd16cc5f408e</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[development-process]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Tue, 04 Jun 2019 17:06:40 GMT</pubDate>
            <atom:updated>2019-07-05T10:36:40.465Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GvemT6J72JHLfknyt6uCNg.png" /></figure><p>Beginners often overwhelm their brain with decisions and things they need to do. Which usually turns into a mess of trying to implement everything at once. Alternatively, programmers end up making very short-sighted decisions that end up becoming problematic later.</p><p>The most important part of programming is that you cannot do everything at once. The human mind is very limited in how much it can process at a time. To combat this limitation, we need to build things piece-by-piece to ensure that everything will fit together nicely.</p><blockquote>Speaking as a builder, if you start something, you must have a vision of the thing which arises from your instinct about preserving and enhancing what is there… If you’re working correctly, the feeling doesn’t wander about.<br> <br> — Christopher Alexander</blockquote><p>The question is — how do we pick the pieces we develop? How do we ensure that our mind and feeling doesn’t wander around?</p><h4>Understanding Value</h4><p>I covered some of the aspects of understanding value already in Value in Software.</p><p><a href="https://medium.com/@egonelbre/value-in-software-f5ec07bcc94b">Value in Software</a></p><p>When we are starting out writing some software, there is so much we could implement. There are also so many ways we could organize and implement things. This overwhelming amount of concerns can quickly push people into Analysis Paralysis.</p><p>One approach would be to start from what is easy to implement; however, if we do that, we may implement many things that are not valuable or even worse, not get to implementing what is valuable at all.</p><p>Let’s take an Issue Tracker as our example to investigate the problems.</p><p>Let’s say we start by implementing login to the system as the first thing. As discussed in another article, it’s not that valuable to people. As a programmer, you might think — I’ve done this many times, it’s easy, and I have a lot of necessary code available already. No doubt, you get something that looks nice and can interact with the page, but what are the downsides?</p><p>For one, we would need to login to the site before we can interact with the actual product; this slows down every step of our development. Similarly, our code base will end up more substantial. Hence, we have more distractions and more parts that could break. We also might get new requests for login, e.g., password recovery, user management, user groups. Triaging extra features sinks time from other vital parts of the code.</p><p>We could also start implementing the end goal. For issue tracking, this might be managing large projects with several teams. However, a big goal can take too much time before it can become practically useful.</p><p>Implementing larger things has an even more significant drawback: we make larger changes and hence we are likely to miss many mistakes.</p><blockquote>Yet, to date, there is little recognition of the following commonsense point: If indeed the programs are so complex, then it is likely that they, too, will be potentially subject to hundreds of thousands, perhaps millions of egregious mistakes of adaption. Here I am not only talking about “bugs” — failures which stop a program from running altogether. I am talking about mistakes of adaptation, ways in which the program fails to do what it is supposed to do, fails to meet the needs of the people who use it, or is more awkward, more annoying, less useful, than it is supposed to be.</blockquote><blockquote>- Christopher Alexander, “The Process of Creating Life”</blockquote><p>How do we avoid making mistakes in the Valuable parts of the system and at the same time, be as valuable as possible?</p><p>It somehow seems obvious and not-so-obvious at the same time to start with the most valuable thing we can complete right now.</p><p>For an issue tracker, the most valuable thing we can quickly complete is the Issue. We can detect the importance already from our conversation about the product. To do anything in the system, we need to be able to manage Issues. The rest of the system has no significant value without it.</p><p>After implementing the “Issue” as the first thing, we can already start using it in code and people may start getting value from it.</p><p>You might be asking, “What about Projects?” It’s quite easy to start multiple instances of the same server and track them on different URL-s.</p><p>Alternatively, “What about login?”. If it’s only for internal use, we could put it up on our intranet and actually trust your coworkers. If we really need outside access, we can add a proxy for authentication.</p><p><em>Just to clarify, I don’t think avoiding “login system” makes a huge difference in the project, however, it is a good example.</em></p><p>There are also other benefits we gain from putting Valuable things first.</p><p>We start to learn about them much sooner and understand how they fit together better, without being distracted by less important things. Maintaining Valuable parts gives us more insight into how it might provide even more value.</p><p>The code usually will reflect this as well. Since these are the things we implement first, the code will be cleaner and contain fewer bugs. Even more, the developers need to always think about why they are doing things, rather than crunching out features.</p><p>It’s important to figure out what is more valuable than something else; otherwise, we may end up back with Analysis Paralysis. Even, if we later discover we were wrong, it’s essential for figuring out what to do.</p><h3>The Simplified Process</h3><p><a href="https://en.wikipedia.org/wiki/The_Nature_of_Order"><em>Christopher Alexander in “The Process of Creating Life”</em></a><em> describes a fundamental process, how life and things we consider living, evolve. The process of creating complex structures, like software, does not differ.</em></p><p><em>However, it’s hard to describe “The Fundamental Differentiating Process” without also describing the foundations of Centers and Structure-Preserving Transformations, which in itself would take several articles.</em></p><p><em>The following is a simplification of the “Fundamental Process” combined with concepts from “The Timeless Way of Building”. It loses some of its generality and beauty in favor of pragmatic concerns. While the following is very useful, it’s not the whole story.</em></p><h4>Structure Follows Value</h4><p>We dedicated a lot of time explaining what Value is and why it is important. To ensure that we build something of value, we need to understand the value it provides and how it provides it. The better we can distinguish value, the better we can make decisions.</p><p><strong><em>Decomposition</em></strong></p><p>When we roughly know what we are building, then we can find the next step by trying to eliminating things. We can visualize the project as a graph of dependencies and associations:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*wVm90DABBpgcv74Skey3wA.png" /></figure><p>We ignore things we cannot implement right now, can mock out, can achieve with other means or live without. Implementing data repositories don’t make sense without actually knowing what we need to store so that we can cross them out:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Hy5BYEME7ciTfgLAxBc3AQ.png" /></figure><p>Since Projects without Issues are less valuable than Issues themselves, we can cross it out.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*PYGoTNiriD_Jrdy9yefMow.png" /></figure><p>Since we can use Issues without Users and tracking Issues are more valuable than tracking Users, we can cross out users.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*x7EUJiNTRRUk9hbGwGGK8g.png" /></figure><p>Since View requires the existence of an Issue, we can also cross it out.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*ectTjcNgeMH2tOn4tBUeoA.png" /></figure><p>Of course, different people may reach different conclusions on what is the most valuable thing, but it’s more consistent than inconsistent. If you are in doubt, ask another person what would they rather have “Issues” or “Issues View.”</p><p>Sometimes the value is so similar that it’s quite impossible to break the tie, but it is critical to do it nevertheless. You could pick the one that is the least understood, the one that is easier to implement or roll a die. If we do not create this ordering, we can end up overwhelming ourselves.</p><p><strong><em>Enhancement</em></strong></p><p>A slightly better approach is to do this in reverse and think of things in terms of unfolding. We ask ourselves which change would enhance the system wholeness and value the most.</p><p>This approach is more difficult to explain and to do, but it also works when we don’t exactly know what we are building. This approach requires feeling and a good understanding of the wholeness of the system.</p><p>You might think that when you start a new project, there is no system to enhance, but there always is. There’s always a reason you are implementing the project. In an Issue Tracker, there exist people, who want to use the system, and want to get an overview of what is happening. There are also many ideas on how things should work. World, People, and Ideas are a part of the system like any piece of code you write.</p><h4>Spiking</h4><p>Implementing ideas one-by-one would eventually cause problems since we might make mistakes from integrating with the rest of the system. We also shouldn’t try to implement too much, since our working memory cannot handle it.</p><p>If we try to break the previously discovered “Value” into 2–4 changes, we minimize the chance of the changes fitting into our working memory. We outline these changes as rough drafts called Spikes. For Spikes, you can use method declarations, type definitions, comments, or anything else that helps to get a feel for how things fit together. We could even do the spiking on a whiteboard or <a href="https://en.wikipedia.org/wiki/Class-responsibility-collaboration_card">CRC cards</a>.</p><p><em>Spiking in software development has its roots in </em><a href="http://www.extremeprogramming.org/rules/spike.html"><em>Extreme Programming</em></a><em> for getting a feel for and understanding whether we are on the right track and notice potential problems. The spiking idea comes from architecture, where architects would put spikes into the ground to get a better feeling of the building and the environment.</em></p><h4>Gradual Stiffening &amp; Cleanup</h4><p>Once the spikes roughly fit and integrate with the rest of the system, we can start making the draft changes. We begin to implement methods, rough out testing, update documents, and so on.</p><p>While making these 2–4 changes, we also need to pay close attention to how things fit together and have a keen eye on how the process flows.</p><blockquote>Recognize that you are not assembling a building from components like an erector set, but that you are instead weaving a structure which starts out globally complete, but flimsy; then gradually making it stiffer but still rather flimsy; and only finally making it completely stiff and strong. We believe that in our own time, the most natural version of this process is to put up a shell of sheet materials, and then make it fully strong by filling it with a compressive fill.</blockquote><blockquote>- <a href="http://www.iwritewordsgood.com/apl/patterns/apl208.htm">“A Pattern Language” by Christopher Alexander</a></blockquote><p>If we use a wrong type name and code doesn’t compile, it can be an important signal that the type could have a better name. We need to have an awareness of the whole.</p><p>This could even result in us moving our spikes or going back to evaluate what is the most valuable thing we are doing. If you are unsure, take notes they help remind where things can be further improved.</p><p>Gradual Stiffening and Cleanup happen together. One is about improving things, and the other is about observing the wholeness and fixing small mistakes.</p><h4>Putting it all together</h4><p>It might not be easy to comprehend this without practical examples, but the best analogy might be Drawing.</p><p>You don’t start drawing like a matrix printer; starting from the top-left corner and proceed to the right side and then the next line.</p><p>More often, the process looks like:</p><p>1. First, you figure out what you are drawing and what are the things you are going to draw <em>(structure follows value)</em> and the purpose of the drawing.<br>2. Then you do a few rough sketches until you see that the picture will work nicely <em>(spiking)</em>.<br>3. Then you start to refine the sketches and draw more delicately <em>(gradual stiffening)</em>.<br>4. Finally, you clean all the sketch lines and color it <em>(cleanup)</em>.</p><p>The basic process of programming is the same. The process also may unfold recursively on different levels of abstraction. In a company, you will have multiple people doing similar processes in parallel.</p><p>This skill of being aware of value and wholeness takes time to develop, but the better you get at it, the more fluid and faster the process becomes.</p><p>In the next article, we’ll take a look at how one iteration of this process might look like:</p><p><a href="https://medium.com/@egonelbre/building-with-value-an-example-fa6280a1aa77">Building with Value: An Example</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dd16cc5f408e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Value in Software]]></title>
            <link>https://medium.com/@egonelbre/value-in-software-f5ec07bcc94b?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/f5ec07bcc94b</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[lean]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Tue, 04 Jun 2019 17:06:19 GMT</pubDate>
            <atom:updated>2019-06-04T17:06:19.940Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/851/1*aWeRJmdnURGR5pMeF8C87w.png" /></figure><p>Why do we write programs in the first place? It’s easy to get lost in the technological details, but this is not the primary goal. This might sound obvious but, <strong>w<em>e need to provide value to people.</em></strong></p><blockquote>There is a central quality which is the root criterion of life and spirit in a man, a town, a building, or a wilderness. This quality is objective and precise, but it cannot be named.</blockquote><blockquote>- Christopher Alexander, “The Timeless Way of Building”</blockquote><p>Understanding <em>Value</em> helps us understand why we are doing things in the first place. If you are not creating something of value, then you are creating waste.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/963/1*ihnErpp_FRDD9zhu3yfz8w.png" /></figure><h4>Valuable</h4><p>To understand <em>Value,</em> we must first understand why do we call things Valuable.</p><p>In the simplest terms, when <strong>X</strong> is valuable to someone <strong>Y</strong>, it means, that <strong>X</strong> has importance to <strong>Y</strong>, it can bring benefit to <strong>Y</strong> in some way.</p><p>The definition is not rocket science:</p><ul><li>the internet is valuable because it can connect people to information with minimal cost,</li><li>a keyboard is valuable because it allows interacting with the computer and</li><li>a text editor is valuable because it allows to change and adjust the text with ease.</li></ul><p>We know and feel when something is valuable to us, and we can empathize when something is valuable to someone else.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8F6-YwId2g1FQwkWejnIRw.png" /></figure><h4>The Context</h4><p>However, understanding Value is not that easy. We must always bear in mind that the value of something possesses is tied to the context.</p><ul><li>If there isn’t information on the internet, then it’s not as valuable.</li><li>If there is no computer for the keyboard, then the keyboard is not that useful.</li><li>If you have nothing to write, then a text editor is not valuable.</li></ul><p>The previous is all common sense, but these examinations help us examine more interesting questions. Let’s take something more challenging.</p><blockquote>Does a ‘login system’ have Value? The first reaction would be to say, <em>“Yes, of course it does.?”</em></blockquote><blockquote>But, have you ever gone home and said: <em>“I got so much value from logging into the system?” </em>I doubt it. Should we conclude that <em>“No, of course logins have no value, they are only an annoyance?”</em></blockquote><blockquote>As you may have already guessed, neither answer is correct.</blockquote><blockquote>- paraphrased example from <a href="http://www.leansoftwarearchitecture.com/">James Coplien</a></blockquote><p>The goal of “logging in” is to protect value, rather than to be of value. If there is no login screen for a system that you don’t use, then it is not of importance to you. When it’s an online bank login, the login is as valuable to you, as how much money you have on your accounts. For the banks, the login system is very important, although it may not be of any explicit value.</p><p>It’s never as simple as <em>“Does something have value?”</em> because we need to take the context into account.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/867/1*H41mdS4tKs4ibxZ8C_1JSw.png" /></figure><h4>Evaluator</h4><p>You should also have noticed that Value will also depend on who is doing the evaluating. We have to keep in mind that there is always an evaluator when looking at value.</p><p>When creating things, we should always look through the eyes of the person benefiting from the Value. In the <a href="https://sites.google.com/a/scrumplop.org/published-patterns/value-stream">value stream</a>, there can be many stakeholders who can benefit from it. Let’s say we are building a wooden box.</p><ul><li>In the simplest case, we are providing value for the end-user. You make a wooden box, and the end-user uses it.</li><li>We could provide value to some other person in your team. You cut a few boards and give them to another person to assemble. The end-user doesn’t care about those boards, and they are not valuable to him.</li><li>We could provide value to ourselves. I could make a jig that allows me to cut boards faster and with less effort. However, neither the person doing assembling the box or the end-user using the box, will care about the jig. But, they do care about the faster cutting.</li></ul><p>We shouldn’t restrict our minds to creating <em>boxes</em>, but instead see the bigger picture.</p><p>How is the box valuable to the end-user, how will they use it? Does he hold very lightweight things in it — this means we can make the box sides thinner and reduce waste. Does he need to store different things, maybe we can add separators into the box?</p><p>Understanding what we create and why it is valuable to people is essential to making the right decisions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GvemT6J72JHLfknyt6uCNg.png" /></figure><h4>Outside the box</h4><p>We should have a bigger view and understand that we can get the same value from multiple solutions. Engineering is about understanding these different solutions and picking the most appropriate one.</p><p>When we look at the “login system” case, if the data can be public, then we won’t need a login. If we are only using it on our computer or intranet, then there is no login necessary.</p><p>Look for multiple solutions, and you can avoid a lot of work this way. Even better, you might end up with a product that is more valuable overall.</p><p>Understanding Value should be at the core of our decision making. It helps to give us clarity about why we are doing something and not doing something else. Always understand how value is provided for the end-user. Otherwise, we are bound to build something unnecessary.</p><p>In the next blog post, we’ll take a look at how we put this understanding into practice.</p><p><a href="https://medium.com/@egonelbre/building-with-value-dd16cc5f408e">Building with Value</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f5ec07bcc94b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Benchmarking with details]]></title>
            <link>https://medium.com/@egonelbre/benchmarking-with-details-1cf3e61d459d?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/1cf3e61d459d</guid>
            <category><![CDATA[benchmarking]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Wed, 03 Apr 2019 10:31:23 GMT</pubDate>
            <atom:updated>2019-06-03T20:07:07.472Z</atom:updated>
            <content:encoded><![CDATA[<p>I’ve been optimizing Go code for a while and trying to improve my benchmarking game.</p><p>Let’s take a look at a simple example:</p><pre>func BenchmarkReport(b *testing.B) {<br>    runtime.GC()<br>    for i := 0; i &lt; b.N; i++ {<br>        r := fmt.Sprintf(&quot;hello, world %d&quot;, 123)<br>        runtime.KeepAlive(r)<br>    }<br>}</pre><p>Running go test -bench . will give us the result:</p><pre>BenchmarkReport-32      20000000               107 ns/op</pre><p>This might be enough for getting a rough estimate where you stand in terms of performance, but a more detailed output is required for optimization. Condensing everything into a single number is bound to be simplistic.</p><blockquote><a href="https://github.com/loov/hrtime">github.com/loov/hrtime</a></blockquote><p>Let me introduce you to the <strong>hrtime </strong>package which I wrote to get a more extensive output from benchmarks.</p><h4>Histogram</h4><p>The first approach to using it is to use hrtime.NewBenchmark. Rewriting the first example as a regular program.</p><pre>func main() {<br>    bench := hrtime.NewBenchmark(20000000)<br>    for bench.Next() {<br>        r := fmt.Sprintf(&quot;hello, world %d&quot;, 123)<br>        runtime.KeepAlive(r)<br>    }<br>    fmt.Println(bench.Histogram(10))<br>}</pre><p>Which will print:</p><pre>avg 372ns;  min 300ns;  p50 400ns;  max 295µs;<br>  p90 400ns;  p99 500ns;  p999 1.8µs;  p9999 4.3µs;<br>      300ns [ 7332554] ███████████████████████<br>      400ns [12535735] ████████████████████████████████████████<br>      600ns [   18955]<br>      800ns [    2322]<br>        1µs [   20413]<br>      1.2µs [   34854]<br>      1.4µs [   25096]<br>      1.6µs [   10009]<br>      1.8µs [    4688]<br>        2µs+[   15374]</pre><p>As we can see that P99 is 500ns, which means that 1% of all our measurements are above 500ns. We can try to optimize this by allocating fewer strings:</p><pre>func main() {<br>    bench := hrtime.NewBenchmark(20000000)<br>    var back [1024]byte<br>    for bench.Next() {<br>        buffer := back[:0]<br>        buffer = append(buffer, []byte(&quot;hello, world &quot;)...)<br>        buffer = strconv.AppendInt(buffer, 123, 10)<br>        runtime.KeepAlive(buffer)<br>    }<br>    fmt.Println(bench.Histogram(10))<br>}</pre><p>And the result:</p><pre>avg 267ns;  min 200ns;  p50 300ns;  max 216µs;<br>  p90 300ns;  p99 300ns;  p999 1.1µs;  p9999 3.6µs;<br>      200ns [ 7211285] ██████████████████████▌<br>      300ns [12658260] ████████████████████████████████████████<br>      400ns [   81076]<br>      500ns [    3226]<br>      600ns [     343]<br>      700ns [     136]<br>      800ns [     729]<br>      900ns [    8108]<br>        1µs [   15436]<br>      1.1µs+[   21401]</pre><p>We can now see that the 99% has gone from 500ns to 300ns.</p><p>If you have a keen eye, you may have noticed that Go benchmark gave an average 107ns/op however hrtime gave us 372ns/op. This is the unfortunate side-effect in trying to measure more — it always has an overhead. The final results include this overhead.</p><p><em>Note: depending on the operating-system the overhead can be significantly less and </em><em>hrtime does support repeated calls inside with </em><a href="https://godoc.org/github.com/loov/hrtime#Histogram.Divide"><em>https://godoc.org/github.com/loov/hrtime#Histogram.Divide</em></a><em>.</em></p><h4>Stopwatch</h4><p>Sometimes you also want to measure concurrent operations. For this there is Stopwatch . <a href="https://godoc.org/github.com/loov/hrtime#Stopwatch">https://godoc.org/github.com/loov/hrtime#Stopwatch</a></p><p>Let’s say you want to measure how long does a send take on a highly contended channel. This, of course, is a contrived example, but roughly shows the idea of how we can start the measurement from one goroutine, stop it in another and finally print it all out.</p><pre>func main() {<br>    const numberOfExperiments = 1000<br>    bench := hrtime.NewStopwatch(numberOfExperiments)</pre><pre>ch := make(chan int32, 10)<br>    wait := make(chan struct{})</pre><pre>// start senders<br>    for i := 0; i &lt; numberOfExperiments; i++ {<br>        go func() {<br>            &lt;-wait<br>            ch &lt;- bench.Start()<br>        }()<br>    }</pre><pre>// start one receiver<br>    go func() {<br>        for lap := range ch {<br>            bench.Stop(lap)<br>        }<br>    }()</pre><pre>// wait for all goroutines to be created<br>    time.Sleep(time.Second)<br>    // release all goroutines at the same time<br>    close(wait)</pre><pre>// wait for all measurements to be completed<br>    bench.Wait()<br>    fmt.Println(bench.Histogram(10))<br>}</pre><h4>hrtesting</h4><p>Of course, writing a separate binary for all of the tests isn’t that convenient. For that there’s <strong>github.com/loov/hrtime/hrtesting</strong>, which provides wrappers for testing.B.</p><pre>func BenchmarkReport(b *testing.B) {<br>    bench := hrtesting.NewBenchmark(b)<br>    defer bench.Report()</pre><pre>for bench.Next() {<br>        r := fmt.Sprintf(&quot;hello, world %d&quot;, 123)<br>        runtime.KeepAlive(r)<br>    }<br>}</pre><p>It will print out 50%, 90%, and 99% percentiles.</p><pre>BenchmarkReport-32               3000000               427 ns/op<br>--- BENCH: BenchmarkReport-32<br>    benchmark_old.go:11: 24.5µs₅₀ 24.5µs₉₀ 24.5µs₉₉ N=1<br>    benchmark_old.go:11:  400ns₅₀  500ns₉₀ 12.8µs₉₉ N=100<br>    benchmark_old.go:11:  400ns₅₀  500ns₉₀  500ns₉₉ N=10000<br>    benchmark_old.go:11:  400ns₅₀  500ns₉₀  600ns₉₉ N=1000000<br>    benchmark_old.go:11:  400ns₅₀  500ns₉₀  500ns₉₉ N=3000000</pre><p>Unfortunately, with Go 1.12 it will print all of the runs of Benchmark instead of just the last. However, with Go 1.13, the output will be much nicer:</p><pre>BenchmarkReport-32   3174566  379 ns/op  400 ns/p50  400 ns/p90 ...</pre><p>And comparing results with <a href="https://godoc.org/golang.org/x/perf/cmd/benchstat">benchstat</a> will work as well.</p><h4>hrplot</h4><p>Leaving the best for last <strong>github.com/loov/hrtime/hrplot</strong>. Using my experimental plotting package, I decided to add a convenient way to plot the benchmark results.</p><pre>func BenchmarkReport(b *testing.B) {<br>    bench := hrtesting.NewBenchmark(b)<br>    defer bench.Report()<br>    defer hrplot.All(&quot;all.svg&quot;, bench)<br>    <br>    runtime.GC()<br>    for bench.Next() {<br>        r := fmt.Sprintf(&quot;hello, world %d&quot;, 123)<br>        runtime.KeepAlive(r)<br>    }<br>}</pre><p>Will create an SVG file called all.svg. It contains a line plot, which shows how much time each iteration took. Second is a density plot, which shows the distribution of timing measurements. And finally a percentiles plot.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/817/1*ChnK-PcNwiEUq2vz6ClemQ.png" /></figure><h4>Conclusion</h4><p>Performance optimization is fun, but having tools to help you out makes it even more enjoyable.</p><p>Go try out <a href="https://github.com/loov/hrtime">github.com/loov/hrtime</a> and let me know what you think.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1cf3e61d459d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Reading Recommendations]]></title>
            <link>https://medium.com/@egonelbre/reading-recommendations-131801d9d0b9?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/131801d9d0b9</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Tue, 29 Jan 2019 16:41:06 GMT</pubDate>
            <atom:updated>2019-01-30T19:19:08.793Z</atom:updated>
            <content:encoded><![CDATA[<h4>for Software Developers</h4><p>I often get asked for recommendations. Here is a list of books and resources I vouch for because I’ve found them invaluable in my journey as a software engineer or have seen them greatly help others.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8vfkUBytW2qS2KDw0xECkA.jpeg" /></figure><p>If you’ve never coded before, then my main recommendation is:</p><p><a href="https://learncodethehardway.org/"><strong>Learn Code The Hard Way</strong></a> course by Zed Shaw is one of those great starting places when you have never seen code before. It has plenty of good tips, tricks and exercises to get you started.</p><p><em>For little ones, playing around with </em><a href="https://scratch.mit.edu/"><em>Scratch</em></a><em> and </em><a href="https://sonic-pi.net/"><em>Sonic Pi</em></a><em> is also great.</em></p><p>A few recommendations specifically for Go:</p><p><a href="https://github.com/ardanlabs/gotraining/"><strong>Go Training</strong></a> resources by Bill Kennedy is a nice introduction to programming in general and what is a good mental model for programming in Go. He covers a variety of topics and it is all free.</p><p><a href="https://www.usegolang.com/"><strong>Web Development With Go</strong></a> course by Jon Calhoun is a comprehensive guide into writing a production ready web application.</p><p><a href="https://www.amazon.com/Programming-Language-Addison-Wesley-Professional-Computing/dp/0134190440"><strong>The Go Programming Language</strong></a> book by Alan Donovan and Brian Kernighan.</p><p>After you have written your first if statements<em>,</em> loops and can manage a 1000 line program.</p><p><a href="https://www.amazon.com/Philosophy-Software-Design-John-Ousterhout/dp/1732102201/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1548418034&amp;sr=1-1&amp;keywords=a+philosophy+of+software"><strong>A Philosophy of Software Design</strong></a> by John Ousterhout is one of those books that helps you get started in moving the right direction for software development mastery. He guides you to find balance in the things you do using clear examples. His list of warning signs helps you notice when things have gone wrong.</p><p><a href="https://en.wikipedia.org/wiki/The_Practice_of_Programming"><strong>The Practice of Programming</strong></a> by Brian Kernighan and Rob Pike is an elegant book which covers a variety of topics from comments to testing and performance.</p><p><a href="https://en.wikipedia.org/wiki/The_Pragmatic_Programmer"><strong>The Pragmatic Programmer</strong></a> by Andrew Hunt and David Thomas is a step towards looking at the bigger picture of software craftsmanship, not just focusing on the coding.</p><p>Once you grasp basics you should continue learning by writing a bigger project — a few packages and around 10,000 lines of code. Otherwise, the following reading might be hard to relate to.</p><p><a href="https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria_for_modularization.pdf"><strong>On the Criteria To Be Used in Decomposing Systems into Modules</strong></a> by David Parnas is a classic that will probably never age. It discusses main concerns when making software modular. It is a great introduction into software architecture.</p><p><a href="http://www.physicsofsoftware.com/"><strong>Physics of Software</strong></a> by Carlo Pescio is a hidden gem that hones your intuition on how software evolves and how different pieces interact. Although these concepts may seem very abstract, I use them frequently.</p><p><a href="http://www.leansoftwarearchitecture.com/"><strong>Lean Architecture: for Agile Software Development</strong></a> by James Coplien and Gertrud Bjørnvig clearly reminds us to not start from <em>technology</em>, but rather from focusing on <em>creating value</em> and on <em>people</em>. In the long run it leads to software that adds more value and expresses ideas clearer.</p><p><a href="https://www.amazon.com/exec/obidos/ASIN/0321125215/domainlanguag-20"><strong>Domain Driven Design</strong></a> by Eric Evans was interesting to me mainly with regards to how to design and figure out the domain part of the software and communicate it clearly.</p><p><a href="https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052"><strong>Working Effectively with Legacy Code</strong></a> by Michael Feathers has sound advice on how to maintain software. I’ve learned so much from refactoring and making things clearer. Maybe even more than from writing things from scratch. Some day, all successful codebases become legacy, so learning how to manage them is essential.</p><p><a href="https://www.amazon.com/Design-Thinking-Enterprise-Innovation-Sustainability/dp/0998477001"><strong>Design Thinking</strong></a> by Dave West and Rebecca Rikner goes into fundamental perspectives, principles, concepts and practices that make design better and more insightful.</p><p><a href="https://www.amazon.com/Introduction-General-Systems-Thinking-Anniversary/dp/0932633498"><strong>An Introduction to General Systems Thinking</strong></a> by Gerald Weinberg is an introduction on how to think about complex and chaotic problems where it is impossible to isolate the parts.</p><p>For performance and algorithms my favourites are:</p><p><a href="http://www.algorist.com/"><strong>The Algorithm Design Manual</strong></a> by Steven Skiena is my favorite algorithmics book. I especially recommend reading the War Stories where it makes clearer how people invent algorithms. It’s not a spark of insight, but rather a gradual improvement over days, months and years.</p><p><a href="https://gist.github.com/jboner/2841832"><strong>Latency Numbers Every Programmer Should Know</strong></a> is one of those tables that you should have roughly memorized for back-of-the-envelope calculations. In general, the skill of estimating is very useful in making smart decisions about performance.</p><p><a href="http://www.dataorienteddesign.com/dodbook/"><strong>Data Oriented Design</strong></a> by Richard Fabian offers a deep dive into using your computer clock cycles efficiently.</p><p><a href="https://www.springer.com/gp/book/9783642148651"><strong>Algorithm Engineering</strong></a> goes in depth in all the different parts of designing algorithms (e.g. how to design, derive and test them properly).</p><p>As programmers we should read code more than we write it. Otherwise it’s easy to end up in our own bubble.</p><p><a href="http://aosabook.org/en/index.html"><strong>The Architecture of Open Source Application</strong></a> contains many different case-studies and interesting practical issues that people needed to solve.</p><p><a href="http://www.satori.org/game-programming-gems/"><strong>Game Programming Gems</strong></a> series contains many very specific and interesting articles on different problems. It’s a great resource for building up your vocabulary about problems.</p><p>Two similar books which I recommend are <a href="https://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047"><strong>Beautiful Code</strong></a> and <a href="https://www.amazon.com/Programming-Pearls-2nd-Jon-Bentley/dp/0201657880"><strong>Programming Pearls</strong></a>.</p><p>Of course you should read code, a lot of it. I can highly recommend reading <a href="https://www.sqlite.org/index.html"><strong>SQLite</strong></a>, <a href="https://github.com/0intro/plan9"><strong>Plan9</strong></a> and <a href="https://www.lua.org/source/"><strong>Lua</strong></a>. Libraries that you use daily are a good place to start.</p><p>While programming you eventually end up working with other people for one reason or another.</p><p><a href="https://sites.google.com/a/scrumplop.org/published-patterns/home"><strong>ScrumPLOP</strong></a> is like a chest of treasures where each pattern is thoroughly thought out and analyses different problems a software team might have. Every pattern has years of experience to back it up. I would recommend to skip the Scrum Guide and go straight to the patterns.</p><p><a href="https://www.amazon.com/Five-Dysfunctions-Team-Leadership-Fable/dp/0787960756"><strong>Five Dysfunctions of a Team</strong></a> goes over major things that can go wrong in a team so you can detect it early and counteract.</p><p><a href="https://rework.withgoogle.com/"><strong>re:Work</strong></a> by Google shares research insights into how to make work environment and communication better.</p><p>Even as a programmer you should have a good grasp on how to design usable things and what a human brain is capable of.</p><p><a href="https://www.amazon.com/Humane-Interface-Directions-Designing-Interactive/dp/0201379376"><strong>The Humane Interface</strong></a> by Jef Raskin is the introductory book on usability and cognetics. I gained a lot of insight into how to measure and understand usability.</p><p><a href="https://en.wikipedia.org/wiki/The_Design_of_Everyday_Things"><strong>The Design of Everyday Things</strong></a> by Don Norman explains human psychology and makes it clear that human interaction is to be expected and failing to take it into account is an error on the designer side.</p><p><a href="https://www.nngroup.com/articles/"><strong>Nielsen/Norman Group</strong></a> if you want to stay up to date with the latest news on usability research or you have a very specific topic that interests you. When I have a usability question then that’s the first place I search.</p><p><a href="http://www.nointerface.com/book/"><strong>The Best Interface is No Interface</strong></a> reminds that the best solution often is not an app or an interaction, but rather the lack of it.</p><p>As programmers we spend most of our time building and maintaining solutions, however reflecting on why and what we are building is just as important.</p><p><a href="https://en.wikipedia.org/wiki/Zen_and_the_Art_of_Motorcycle_Maintenance"><strong>Zen and the Art of Motorcycle Maintenance</strong></a> by Robert Pirsig is an exploration of what is “quality” and what matters in life.</p><p><a href="https://en.wikipedia.org/wiki/The_Nature_of_Order"><strong>The Nature of Order</strong></a> by Christopher Alexander is a formulation of principles that create good environments and life in the world. It’s a description on how to make life better using design.</p><p><a href="https://www.amazon.com/Patterns-Software-Tales-Community/dp/0195121236"><strong>Patterns of Software</strong></a> by Richard Gabriel contains many insightful essays on the nature of building software.</p><p>Somewhat more specialist subject is networking, but nevertheless, you will end up using networks one way or another:</p><p><a href="https://blog.erratasec.com/2012/06/falsehoods-programmers-believe-about.html"><strong>Falsehoods programmers believe about networks</strong></a> and <a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing"><strong>Fallacies of distributed computing</strong></a> are very short articles, but will make it clear why networking code is difficult, and therefore make you approach the field with greater reverence.</p><p><a href="https://www.apress.com/gp/book/9781484226919"><strong>Network Programming with Go</strong></a> by Jan Newmarch goes over multiple layers of network programming with really nice explanations.</p><p><a href="http://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf"><strong>Why Do Computers Stop and What Can Be Done About It?</strong></a> by Jim Gray is a classic and a great introduction to dealing with the inevitable failure of systems.</p><p><a href="http://erlang.org/download/armstrong_thesis_2003.pdf"><strong>Making reliable distributed systems in the presence of software errors</strong></a> by Joe Armstrong talks about building reliable systems that can survive in the harshest of conditions.</p><p>And now the miscellaneous:</p><p><a href="https://www.amazon.com/Structure-Interpretation-Computer-Programs-Engineering/dp/0262510871"><strong>Structure and Interpretation of Computer Programs</strong></a> by Gerald J. Sussman and Hal Abelson is a classic that teaches how to bend programming to your own needs.</p><p><a href="https://www.nand2tetris.org/"><strong>NAND2Tetris</strong></a> course is an introduction to building a virtual computer from the basic elements (almost). It covers machine language, computer architecture, assemblers, high-level languages etc. All in a course form. For an addendum you can watch Ben Eater’s <a href="https://www.youtube.com/watch?v=HyznrdDSSGM&amp;list=PLowKtXNTBypGqImE405J2565dvjafglHU"><strong>Building an 8-bit breadboard computer</strong></a>.</p><p><a href="https://github.com/kdeldycke/awesome-falsehood"><strong>Awesome Falsehoods</strong></a> contains a series of articles by different authors exploring various topics in depth, usually things that people get wrong. Just learning about names is enough to take precautions in every other concern.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=131801d9d0b9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Thoughts on Code Organization]]></title>
            <link>https://medium.com/@egonelbre/thoughts-on-code-organization-c668e7cc4b96?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/c668e7cc4b96</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Tue, 20 Nov 2018 11:30:11 GMT</pubDate>
            <atom:updated>2018-11-29T07:44:24.618Z</atom:updated>
            <content:encoded><![CDATA[<p>There are many ways code could be structured. I was pondering a lot what is the best way. I rather reached an unsatisfying conclusion — depending on the situation one could be better than some other. Structuring code means to slice up the program in different ways for better comprehension.</p><p>One of my major insights was:</p><blockquote>When the code-base is less than 30,000 lines of code, then code organization isn’t a big hindrance in getting work done.</blockquote><p>This number also suggests that you cannot draw any significant conclusions from code-bases that have less than 30K LOC (lines of code).</p><p><em>Note: the actual size is actually more related to how much variance and how many ideas the implementation has. For example, on a website you probably would need 5 different domain ideas, where each is represented by 5 entities, all of them being manipulated and inter-connected. The 30K LOC cutoff serves more as a heuristic.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6FpJv5okieg4Q59vP5A-XQ.png" /><figcaption><a href="https://archive.org/details/vocabularioenlen00gilb">Vocabulario en lengua de Mechuacan</a></figcaption></figure><h4>Alphabet</h4><p>Why do people organize things in the first place? First, it helps with finding things. Take dictionary for example. I can find “serendipity” just by finding the letter “s” and then each following letter one at a time.</p><p>In a dictionary with words sorted in alphabetical order each word acts like a road sign pointing from where you are to where you want to go.</p><p>It would be wrong to conclude that organizing everything alphabetically is the right thing to do. Often the question is how to organize. For example when I would like to find all words ending with “-logy” then alphabetical order would be very difficult to use. There are specialized dictionaries that help with that exact question, but those in turn make finding a words with the same beginning more difficult.</p><p>When organizing we need to think:</p><blockquote><strong>Where is the value in a specific order?</strong></blockquote><p>One important implication of this is, that when we make something easier, something else becomes more difficult. The code structure should cater to our problems and needs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zJeWO9jRsoN5_PUyMG1Ddg.png" /></figure><h4>No Organization</h4><p>What does disorganized mean? It’s easy to state that something is disorganized, but how do we know whether something is organized?</p><p>Organization can be largely separated into three principles:</p><ul><li>grouping</li><li>showing similarity</li><li>showing relationships</li></ul><p>Grouping creates a unifying idea that helps us find or situate something. In psychology terms, we create a new chunk out of multiple ideas. Showing relations or similarity helps us find the other idea and how it is situated in the bigger picture.</p><p>As stated before, a dictionary has alphabetical order. This creates implicit groupings. Each word might have a description or “see also” notes, which show relations to other words.</p><p>So, when we talk about no organization, it often means one of the following:</p><ul><li>there is no understandable grouping</li><li>it is unclear how something is related to everything else</li></ul><p>It’s important to notice that it’s about “understanding” and “clarity”. When you look at a reverse word dictionary, the usefulness probably won’t be visible immediately. It might be easy to say it’s unorganized or useless. However, when you understand the usefulness it “magically” becomes organized.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4GcGl2c7wpvyGwvClaDgtg.png" /><figcaption><a href="https://archive.org/details/rhymingspellingp00walkrich/">A Rhyming, Spelling, and Pronouncing dictionary</a></figcaption></figure><p>In most cases we also need to consider ease-of-learning the organization. Complicated approaches can become an overhead when trying to modify artifacts. A simplistic approach may not give useful benefits. More on that later.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*5BJKIF4GeuNZYYKO_yt-Fw.png" /><figcaption><a href="https://github.com/livingcomputermuseum/ContrAlto">Smalltalk-76 Code Browser</a></figcaption></figure><h4>Code</h4><p>Code is mainly organized using the following language constructs:</p><ul><li>folders and files;</li><li>modules, units or packages;</li><li>types, classes, nested classes and objects;</li><li>interfaces, traits, contexts, roles and aspects;</li><li>methods, functions, nested functions and code blocks.</li></ul><p>However, there are other ways to describe structures:</p><ul><li>spatial placement of code structures;</li><li>similar naming (for example <a href="https://en.wikipedia.org/wiki/Hungarian_notation">Hungarian notation</a> or <a href="https://en.wikipedia.org/wiki/Software_design_pattern">Design Patterns</a>);</li><li>regions (<a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-region">such as in C#</a>);</li><li>comments, documentation and diagrams.</li></ul><p>It might be easy to forget that types serve as a way to organize code. Things derived from the same base-class (or object) are explicitly related. Using another type as a field in a structure is an implicit link to understanding that structure as well. The following descriptions applies to any or combination of these.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HXg30J_8_Fg7SQyTpEgXoA.png" /></figure><h4>Canonical Layout</h4><p>One of the most obvious ways of organizing things is the same way as everyone else does. This gives rise to structures that look very similar to each other.</p><p>You can recognize Java by its structure lib, src/main/java, src/main/resources, src/test etc. Or Linux by etc, mnt, dev. You also have model, view, controller. But there’s no real reason for naming these folders that way other than that everyone else does it the same way.</p><p>I’m not talking about the specific content that these folders have, but just the names. It could be library, instead of lib; it could be mdl or models instead of model. Keeping consistency can help a lot with understandability.</p><blockquote>Familiarity is a useful feature as it helps us understand new things quicker by relying on what we know already.</blockquote><p>My own rule is that when I cannot argue for more than 5% better results by naming it some particular way, then I will use the canonical approach; because the hit from non-familiarity (see <a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment">principle of least astonishment</a>) when other programmers read it, is bigger.</p><p>Often there are reasons why something ended up being named like the way it did. Usually they are human reasons. Someone thought that “this is clear to me” and other people picked it up. The benefit comes from familiarity rather than anything else.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RLNAX4xnggu11N4tmkQiQg.png" /></figure><h4>Group by Dependency or Technology</h4><p>Separating things by having a common dependency is another easy way of categorizing.</p><p>For example you might have a component that relies on Windows or Linux system calls, so it can be helpful to separate them with a folder. Similarly a database implementation built on top of Postgres and MongoDB might end up in different files or folders.</p><p>Separating things by dependency often makes it easier to do compilation where you don’t pull in a particular dependency. Similarly, separating by dependency allows you to focus more on the “abstraction” that the different dependencies need to implement.</p><p>This clear separation might end up with more lines of code compared to using things like <a href="https://en.wikipedia.org/wiki/C_preprocessor#Conditional_compilation">C-macros </a><a href="https://en.wikipedia.org/wiki/C_preprocessor#Conditional_compilation">IFDEFs</a>. Similarly, the “abstraction” that describes both adds more code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*804r9bt-BKfRfAiHT8vuLA.png" /></figure><h4>Group by Team</h4><blockquote>“organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.”<br>- M. Conway</blockquote><p>Grouping by team makes it clearer when coordination between teams is needed. For example ui, backend and db need expertise from different teams. Hence, it becomes more obvious who is responsible for which part of the codebase.</p><p>However such separation can break locality of information of how something works. Locality of information itself can make harder to grasp the system as a whole. The isolation itself may result in ui, backend and db not fitting together nicely.</p><p>A change in the model often propagates through all of the groups. This increases communication or it may require more effort to define stable interfaces.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fb9sApi2Ws51aZUCJTZibQ.png" /></figure><h4>Group by Use</h4><p>A grouping that focuses on usability is “group things that are used together”. Sometimes it is difficult to define a single clear grouping other than these things are used together.</p><p>Most languages have some sort of math or string manipulation package, with functions like power, log and trim, join.</p><p>Effectively these groups are <em>toolboxes</em> that you can use. The problem with such toolboxes is that they can easily degrade into <em>kitchen sinks</em>, where all sorts of arbitrary things end up together. You need to clearly figure out what belongs or doesn’t belong in there to avoid such problems.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TielsildYeRhG42Vj-jfgA.png" /></figure><h4>Group by Connections</h4><p>One similar approach to grouping by use, is grouping by connections. We can see this in abundance when looking at declarations of classes and it’s methods.</p><p>A method is tied to the class declaration because it operates on the fields that a class has declared. Of course it is declared there because we see it as a behavior of the type. We declare them together, because they are strongly bound together, so it helps to keep a locus of attention.</p><p>This is not limited to class oriented languages, all languages have a preference of keeping functions, procedures or predicates close to the type, datatype or struct.</p><p>The problem with this approach is similar to grouping by use. Commonly used structures can start accumulating features from all of the places it’s being used. This can make the structure itself less clear. Good examples are data-structures (<a href="https://www.scala-lang.org/api/current/scala/collection/Seq.html">Scala</a>, <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=netframework-4.7.2#methods">C#</a>). Of course, you do get a lot of convenience from this approach.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Emh96kS7Z6vUsbp9BsprBQ.png" /></figure><h4>Group by Classification</h4><p>Grouping by classification is about organizing things based on the function that things serve in a bigger picture.</p><p>One of the most recognizable ones would be <a href="https://github.com/jwipeout/rails-directory-structure-guide">Ruby on Rails folder structure</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/636/1*RVYccWDiKoWEch9wDUkP0w.png" /></figure><p>Many frameworks force a particular folder structure. It’s common to see folders such as models, views, controllers and components. For games you would see folders such as textures, scripts, materials and meshes.</p><p>In some projects there is also a single separate folder such as plugins that serves as pluggable parts. This helps to organize and make it clear that the rest of the system doesn’t depend on them directly.</p><p>Separation by category can help and simplify framework implementation to automate and find things. For example web renderer can look views folder to find appropriate content to render. Similarly, micro-architecture problems are more visible. For example, it is much more visible when “models” requires “views” by accident.</p><p>With frameworks that require such layout it’s necessary to learn the proposed structures. The more complicated the layout, the more learning is needed. However, given a good layout this can significantly help getting small and medium sized projects up and running, since you don’t have to relearn how to do everything.</p><p>However the bigger the project the more likely it is that you need <a href="https://www.youtube.com/watch?v=FAZ4GjPKmVI">exceptions in your design</a>. The fixed folder structure means you either end up creating new folders for capturing the exception or the folder becomes “dirty” because the artifacts don’t necessarily align with the category.</p><p>The classification problem can also happen with inheritance. <a href="http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/">“Evolve Your Hierarchy”</a> describes this problem in game programming context. For example having a base class “Movable” and then a derived “Vehicle”. However, when we add a “Trebuchet”, which needs to be deployed, it makes the object “Unmovable”. We would then move all the different behaviors up to the base class or create a new base-class “MostlyMovable”. We can manage it, but the fundamental problem is about treating it as a classification problem rather than composition of properties.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s8sc8Y1UoeyAhYS-S4bVjw.png" /></figure><h4>Group by Feature</h4><p>Instead of thinking in terms of classification we can also think of features that work together.</p><p>For example, you would end up with ideas blog, admin, user, comment, feed for a blog site. You still might have models and views, but in these folders (blog/model , blog/view etc).</p><p>This organization makes it much clearer what the software does and how it’s built. It also shows how different things communicate. It places less importance on technical considerations and more on the value proposal of the whole system.</p><p>It also makes it much easier to have variation in how things are implemented. For example some particular feature might much better be expressed as a model-view or page.</p><p>You can still have <a href="https://en.wikipedia.org/wiki/Cross-cutting_concern">cross-cutting features</a>, such as administration of pages. So you would need to figure out how to exactly implement it. One way would be to have a single folder admin with admin/blog, admin/users etc. An alternative would be blog/admin, user/admin etc. In the first case we make it easier to write the admin system itself. In the second case it’s easier to manage a particular feature in isolation.</p><p>When we have given less importance to technical considerations it becomes more difficult to enforce a particular micro-architecture and consistency between features. However, it is still possible to use code-review and specialized linters can also ensure such constraints.</p><p>With performance oriented projects it might become much more difficult to ensure that the system as a whole works tightly and with low-memory, because we may have separated the pieces that are commonly running together.</p><p>This approach also has problems when prototyping, when you are still figuring out what “features” you need.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vs27c3QQKgXAhw2VkJvUPQ.png" /></figure><h4>Group by Value</h4><p>In all of the previous groupings we have discussed pros and cons of different approaches. “Group by Value” can be seen as an mix of all them.</p><p>You start by figuring out what is “valuable” and important in your project. This can vary in different sections, classification or features. Then derive the organization.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/744/1*N499kLJU-iuwoL6zVrjTWg.png" /></figure><p>This kind of organization can be seen in many projects that do not have an idiomatic way of writing things. You can look at <a href="https://github.com/kubernetes/kubernetes/tree/master/pkg">Kubernetes</a> as an example that uses many of these. Similarly many other command-line utilities, database implementations.</p><p>This kind of structure happens quite naturally when taking an incremental approach to building things.</p><p>One of the major downfalls of this approach is that it is difficult to explain and difficult to do well. Contrary to all the previous organization approaches, you need to be able to evaluate pros/cons of all of them instead of just one. Explaining these ideas to junior programmers is also difficult.</p><p>Grouping by value requires a good understanding of why and how your software is valuable. Getting a deep understanding can take a lot of time. And as I mentioned in the beginning, the extra effort of organizing may not pay-off when your project is small. Then again, with large projects forcing people to think about what is valuable can have big benefits, not just in code-organization, but also the product itself.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZzbGHG3jWKAXIQevZXjKtw.png" /></figure><p>I try to think less about organizing code and more about organizing ideas about the software. Then again, it’s about finding a good balance between different approaches. There is no “right way”, but they do give more clarity to different aspects of a project.</p><blockquote>“Just organizing things” doesn’t necessarily create value.</blockquote><p>The question is, which organization gives the most value to you?</p><p><em>If you found this article useful you can buy me a coffee at </em><a href="https://www.buymeacoffee.com/egon"><em>https://www.buymeacoffee.com/egon</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c668e7cc4b96" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Manipulating JSON Fields]]></title>
            <link>https://medium.com/@egonelbre/manipulating-json-fields-f787d56bbd1d?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/f787d56bbd1d</guid>
            <category><![CDATA[go]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Wed, 01 Aug 2018 14:24:45 GMT</pubDate>
            <atom:updated>2018-08-12T10:07:25.752Z</atom:updated>
            <content:encoded><![CDATA[<p><em>All the code can be found here </em><a href="https://github.com/egonelbre/exp/tree/master/fields"><em>https://github.com/egonelbre/exp/tree/master/fields</em></a></p><p>On reddit there was a question:</p><iframe src="https://cdn.embedly.com/widgets/media.html?type=text%2Fhtml&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;schema=reddit&amp;url=https%3A//www.reddit.com/r/golang/comments/8y2zfc/looking_for_idiomatic_way_to_do_this/&amp;image=https%3A//i.embed.ly/1/image%3Furl%3Dhttps%253A%252F%252Fi.redditmedia.com%252F6NRaaAy666PTmx_uWsv2-zqU3GJ1kMVtqkVjIPUvrVw.jpg%253Fs%253Ddd4dced9feea5fdc084c8f154e2ed08f%26key%3Da19fcc184b9711e1b4764040d3dc5c07" width="600" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/33244f8454acac6191bfb2a6f5b9a873/href">https://medium.com/media/33244f8454acac6191bfb2a6f5b9a873/href</a></iframe><p>Before diving into answering it’s always useful to first dive into the question. It’s easy to lose track on what the actual problem is. Often by creating a better underlying model we can simplify or eliminate the problem altogether.</p><p>After a few questions I got that the <a href="https://www.reddit.com/r/golang/comments/8y2zfc/looking_for_idiomatic_way_to_do_this/e29c1ud/?context=3">input JSON looks like this</a> (slightly simplified):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4fe6b4c30b6dc01f7f8265144c3b1e6b/href">https://medium.com/media/4fe6b4c30b6dc01f7f8265144c3b1e6b/href</a></iframe><p>The goal of the program is to write code that computes with these values according to names. For example:</p><pre>&quot;Alpha&quot; + &quot;Gamma&quot; = 25 float</pre><p>We’ll ignore the multiplier in this post. Unfortunately he wasn’t able to share the business problem, which could provide even more insight.</p><h3>Interface</h3><p>The initial implementation was based on using interfaces. Interfaces are indeed one of the solutions for handling variability of the type. The most basic implementation could look something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eecdc82190f04e4245061032c14137e5/href">https://medium.com/media/eecdc82190f04e4245061032c14137e5/href</a></iframe><p>The content can be parsed from JSON using using a regular struct and unmarshal:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/da3f0c2ca2e2bc55fab9115b1af2b483/href">https://medium.com/media/da3f0c2ca2e2bc55fab9115b1af2b483/href</a></iframe><p>There are other packages that could be more performant, but it’s not a vital part and we can always switch it out later if needed.</p><p>Now the question is, how do we write the code. Just writing fields[&quot;Alpha&quot;].Add(fields[&quot;Beta&quot;]) , wouldn’t work since we only handle things that have specific type.</p><h3>Type-Switch</h3><p>I guess the brute-force implementation could use a type-switch to do this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/863efe2c8d2a39f4396c0e427cdd3cc2/href">https://medium.com/media/863efe2c8d2a39f4396c0e427cdd3cc2/href</a></iframe><p>We use “Error” field type to propagate errors around. It also could be done with manual error propagation or panic, but the Error field seemed a nice solution. Finally we will use all of these things together as:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1caa0fd90ac240e251a4d2b37a3cc8ed/href">https://medium.com/media/1caa0fd90ac240e251a4d2b37a3cc8ed/href</a></iframe><p>However, already with implementing two types a single operation becomes very verbose. This is also worsened with each new operation.</p><p>There’s a variation for this type-switch. Instead of using concrete type in Add we can use the interface Field. However this has the problem that it ties all the different Field implementations together.</p><pre>func (a *Uint) Add(b Field) Field { ...</pre><h3>Type-Map</h3><p>We can avoid some of the boilerplate by using a type-map, which creates a mapping from types to a function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d4de2433f8172ca861761ebe7f3177bd/href">https://medium.com/media/d4de2433f8172ca861761ebe7f3177bd/href</a></iframe><p>For each “name and type pair” we assign a corresponding function. We’ll implement the generic Add / Sub in by looking up the function with the right signature. We can see a variation of this in <a href="https://github.com/robpike/ivy/blob/master/value/binary.go#L159">Ivy</a>. It has some nice benefits, like making type-promotions easier.</p><p>However, due to interfaces we end up with a lot of different type-conversions to make this happen. We lose all of the type-safety that our language gives us. Similarly it is easy to make a mistake when specifying the functions. That can be somewhat fixed by using reflection to find the func arguments.</p><p>This can be a pretty good solution when we need to mix multiple types and the “math” comes from the end-user and not the programmer. In that scenario we cannot rely on the language type-safety anyways.</p><h3>Reflection</h3><p>Let’s consider whether using varying types is necessary at all. When we have the correct types from the beginning, we won’t have to deal with the conversions in the first place.</p><p>We can try to implement something similar to JSON unmarshaling on arbitrary types. In essence:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e429fc56ba6ac9841b24e0e7868a179d/href">https://medium.com/media/e429fc56ba6ac9841b24e0e7868a179d/href</a></iframe><p>To make this implementation work, we first need to unmarshal JSON data into a structure. This is quite similar to the previous cases:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6f65b0beb470cf38630b51debcb9bafe/href">https://medium.com/media/6f65b0beb470cf38630b51debcb9bafe/href</a></iframe><p>We then need to walk over all of the necessary fields with reflection. For each result field we also will find the corresponding field from JSON.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6737184220bb2b43e17f7b737b76d6bc/href">https://medium.com/media/6737184220bb2b43e17f7b737b76d6bc/href</a></iframe><p>And finally assign the value to the field:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5569ba9e5a45c29fa5cc4a398db15ca7/href">https://medium.com/media/5569ba9e5a45c29fa5cc4a398db15ca7/href</a></iframe><p>This solution is nice and neat to use, however extending it with new types would be somewhat annoying. Working with reflection is error-prone and easy to miss specific cases.</p><h3>Composed serialization</h3><p>We can avoid reflection by using a thing I call <a href="https://medium.com/@egonelbre/specification-types-ed9ddf35ec8f">composed serialization</a>. This is how we would write the Field interface:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/19f32ac771f5f8296cdbf998c8c5b5d8/href">https://medium.com/media/19f32ac771f5f8296cdbf998c8c5b5d8/href</a></iframe><p>Notice that the Value is a pointer not the value itself. This allows us to assign the value to an arbitrary place. We can assign the values like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f8738463560ce76caf01eaaed92d8102/href">https://medium.com/media/f8738463560ce76caf01eaaed92d8102/href</a></iframe><p>Finally we can use these all together as:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5918df523c78802cc5b1e6f6adb4e43f/href">https://medium.com/media/5918df523c78802cc5b1e6f6adb4e43f/href</a></iframe><p>We can make this little shorter by hiding the JSON part, but it’s not that important for the example. The neat thing is that we can add new field types without having to change the scanning part. Of course this implementation comes at the annoyance of having to explicitly write out the target type twice.</p><h3>Conclusion</h3><p>This was another example in how a single problem can be solved in multiple ways. I definitely skipped many possible solutions. Remember that none of these is the “best solution”, each of them has different tradeoffs.</p><p>It’s easy to get stuck in a mindset where you want to solve a problem in a particular way. However, there are always many many solutions. Exercising this skill of infinite possibilities helps to find solutions that take less time to implement are more performant or easier to use.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f787d56bbd1d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dealing with Code on Medium]]></title>
            <link>https://medium.com/@egonelbre/dealing-with-code-on-medium-c40016e8b1f3?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/c40016e8b1f3</guid>
            <category><![CDATA[medium]]></category>
            <category><![CDATA[writing]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Fri, 27 Jul 2018 09:12:36 GMT</pubDate>
            <atom:updated>2018-07-28T11:10:57.917Z</atom:updated>
            <content:encoded><![CDATA[<p>Yesterday my frustration meter with Medium-s code editing finally hit the limit. The problem has been described in multiple places. Just to describe why I’m annoyed with it.</p><p>First of all, there are quite a few ways of adding code to a Medium.com, however all of them are frustrating or lacking in some way.</p><h4>Code Blocks</h4><p>First of all the integrated code blocks. In essence they look like this:</p><pre>package main</pre><pre>func main() {<br>    println(&quot;Hello World&quot;)<br>}</pre><p>At least in theory. When you use tabs, this happens:</p><pre>package main</pre><pre>func main() {<br> println(&quot;Hello World&quot;)<br>}</pre><p>When you copy-paste from Visual Studio Code, this happens:</p><pre>package main</pre><pre>func main() {</pre><pre>println(&quot;Hello World&quot;)</pre><pre>}</pre><p>When you edit, it will behave in all sorts of weird ways. I don’t really mind the no-syntax-highlighting, but the font-size could be smaller. Anytime I tried to use them then editing any indentation, deleting and undo made it break.</p><h4>Gist</h4><p>You can also link to gist.github.com, which looks much better:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/63e3f77953fea4207d8f49e1c507234e/href">https://medium.com/media/63e3f77953fea4207d8f49e1c507234e/href</a></iframe><p>However, the problem is when you try to add multiple code snippets. My most recent post had 12 different code paragraphs. When you put multiple files into a single gist you cannot link them to individually… so you end up with a mess like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7c8c5ac370503f543db61570331e0d4b/href">https://medium.com/media/7c8c5ac370503f543db61570331e0d4b/href</a></iframe><p>Of course you can create separate gists, but manually making 12 of them is pretty annoying.</p><h4>Medium API</h4><p>Medium does support creating new posts via an API, where you can provide a markdown or html file. However the issue is that you cannot later update that post. There’s even an <a href="https://github.com/Medium/medium-api-docs/issues/52">issue posted with no feedback from Medium</a>.</p><p>I understand the complications. Since Medium tracks the highlights that people have made, updating the content is not as trivial as updating the html. However it definitely isn’t that complicated either since structural diffing does work.</p><h4>Screenshots</h4><p>The least frustrating approach I’ve found was using code screenshots. Obviously, this is very annoying for readers.</p><h3>Conclusion</h3><p>All in all, the general experience of sharing posts on Medium, is pretty good. The citing, highlighting and getting feedback part is really great. Interacting with comments is somewhat annoying and the stats aren’t that great. However the code part is a great deal frustrating.</p><p>None of the solutions I previously mentioned were usable, so I ended up writing my own “solution”.</p><p><a href="https://github.com/loov/gistsnip">loov/gistsnip</a></p><p>The idea was to take an existing working code, add some annotations and then the tool will automatically create gists based on the comments.</p><p>For example from the following code it will create automatically two gists:</p><pre>func main() {<br>    <strong>//gistsnip:start:loop</strong><br>    for i := 0; i &lt; 100; i++ {<br>        fmt.Println(i)<br>    }<br>    <strong>//gistsnip:end:loop</strong><br><br>    <strong>//gistsnip:start:example</strong><br>    fmt.Println(&quot;hello world&quot;)<br>    <strong>//gistsnip:end:example</strong><br>}</pre><p>Of course, when you modify your code, it will update the existing gists rather than creating new ones. The folder where you run gistsnip contains a file called .gistsnip, which contains necessary metadata for it.</p><p>You can see a how your medium post looks like in:</p><p><a href="https://medium.com/@egonelbre/server-and-a-database-8e19b2b33c21">Server and a Database</a></p><p>And the code repository for the medium post:</p><p><a href="https://github.com/egonelbre/db-demo">egonelbre/db-demo</a></p><p>This should allow me to continue working on Medium, until I find a better solution. The migration is going to be annoying, but probably worthwhile.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c40016e8b1f3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Server and a Database]]></title>
            <link>https://medium.com/@egonelbre/server-and-a-database-8e19b2b33c21?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/8e19b2b33c21</guid>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[go]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Thu, 26 Jul 2018 10:22:34 GMT</pubDate>
            <atom:updated>2018-07-26T20:13:15.927Z</atom:updated>
            <content:encoded><![CDATA[<p>I have seen quite a few questions on how to setup a basic server and database in Go. I’ll show few versions, with each one handling more variability and more complex situations.</p><p>We are going to take a really small website, where you can submit comments and it will display them. We will cover interaction with the server and database, however we will mostly ignore the different ways of rendering the content and writing business logic. <em>Also, you should probably have some familiarity with Go databases and servers.</em></p><p><em>You can imagine this as an example of </em><a href="https://medium.com/@egonelbre/learning-code-readability-a80e311d3a20#03c9"><em>“Infinite Possibilities”</em></a><em> exercise.</em></p><h3>YOLO</h3><p><em>Code at </em><a href="https://github.com/egonelbre/db-demo/tree/master/00_yolo"><em>https://github.com/egonelbre/db-demo/tree/master/00_yolo</em></a></p><p>This is the version, that takes the least effort. This approach can be described as “throw everything together”.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/12020a4c3d5c42bcc91577b94d384fe9/href">https://medium.com/media/12020a4c3d5c42bcc91577b94d384fe9/href</a></iframe><p>Everything in this file is mingled together and quite hard to follow. Any longer than this and it becomes unmaintainable.</p><p>However, this can be used as our first iteration until we figure out what needs to be done.</p><h3>Functions</h3><p><em>Code at </em><a href="https://github.com/egonelbre/db-demo/tree/master/01_funcs"><em>https://github.com/egonelbre/db-demo/tree/master/01_funcs</em></a></p><p>The first step towards separating HTTP from data storage is to use functions. We create functions for different interactions and then provide the database connection as the first parameter.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7edcb68b9fd0212efce6dc7fa776b5dc/href">https://medium.com/media/7edcb68b9fd0212efce6dc7fa776b5dc/href</a></iframe><p>We could also separate these functions into a separate folder. Regardless the database methods are harder to find, especially when there are many such functions.</p><h3>Repository</h3><p><em>Code at </em><a href="https://github.com/egonelbre/db-demo/tree/master/02_repo"><em>https://github.com/egonelbre/db-demo/tree/master/02_repo</em></a></p><p>Instead of keeping separate functions we can attach them to a type.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/21abec78e9dece12e07e7c43dff6fcc7/href">https://medium.com/media/21abec78e9dece12e07e7c43dff6fcc7/href</a></iframe><p>Where the comments repository looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae3e1bcd46d5ca780cf1bfb845e6a575/href">https://medium.com/media/ae3e1bcd46d5ca780cf1bfb845e6a575/href</a></iframe><p>This keeps the comment related database interactions in a single place.</p><h3>Server</h3><p><em>Code at </em><a href="https://github.com/egonelbre/db-demo/tree/master/03_server"><em>https://github.com/egonelbre/db-demo/tree/master/03_server</em></a></p><p>Before we refactor the database more, we need to make the server clearer. The endpoint wiring in main didn’t look that nice. Instead let’s try this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/be3efcdcd17630d0612c1c7941fed88b/href">https://medium.com/media/be3efcdcd17630d0612c1c7941fed88b/href</a></iframe><p>The Server looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/68df99f2033c85584b8352029fc240d8/href">https://medium.com/media/68df99f2033c85584b8352029fc240d8/href</a></iframe><p>We have removed the global Comments repository and added it as a field to Server. Also, Server has become much easier to test.</p><h3>Interface</h3><p><em>Code at </em><a href="https://github.com/egonelbre/db-demo/tree/master/04_interface"><em>https://github.com/egonelbre/db-demo/tree/master/04_interface</em></a></p><p>It’s usually nice not to depend on the database implementation directly as it means we have to use specific database implementation for testing. By separating the Comments implementation and interface we make clearer our requirements and how we fulfill those requirements.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/373fda05ffca81ed655dd0fb3418aadb/href">https://medium.com/media/373fda05ffca81ed655dd0fb3418aadb/href</a></iframe><p>Since we wanted to separate them, the folder structure needs to change as well:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3de0d73d0b25a186d7fd87da77e63042/href">https://medium.com/media/3de0d73d0b25a186d7fd87da77e63042/href</a></iframe><h3>Scope</h3><p><em>Code at </em><a href="https://github.com/egonelbre/db-demo/tree/master/05_scope"><em>https://github.com/egonelbre/db-demo/tree/master/05_scope</em></a></p><p>In the future we may need more repositories than Comments. There are few ways that we could handle it. One is to add all methods to a single type. However, that approach can get messy and unorganized after four different repositories.</p><p>The other approach is to create a separate implementation and pass them as arguments to Server. It has somewhat similar problem that we might end up with a lot of arguments.</p><p>We can also use hierarchical interfaces:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ceda74ec5693d9083e25c799ff1b7535/href">https://medium.com/media/ceda74ec5693d9083e25c799ff1b7535/href</a></iframe><p>It might look that this is too complicated and unclear why this is beneficial. Let’s take a look at when we have more than one repository and have added basic access control:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e79124b2f1b55bbec1d45be6c5b46510/href">https://medium.com/media/e79124b2f1b55bbec1d45be6c5b46510/href</a></iframe><p>We can implement this interface as:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ac5cddf2df529c1ee5e0df28fafff7a0/href">https://medium.com/media/ac5cddf2df529c1ee5e0df28fafff7a0/href</a></iframe><p>Of course we can use different combinations of extending the DB.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/625bb35a09bf05a64e5e6797aff0ce68/href">https://medium.com/media/625bb35a09bf05a64e5e6797aff0ce68/href</a></iframe><p>These small things help us avoid forgetting different access checks without having to create a separate argument for each of the methods.</p><h3>Conclusion</h3><p>I think these five approaches should cover most of the needs, however specific scenarios might have more interesting solutions. Given a CRUD situation, you might need ORM. Sometimes, you may need a solution with multiple database engines (for example, one for content, one for text-search).</p><p>I think the most important thing is:</p><blockquote><strong>The right solution is the easiest that works for you.</strong></blockquote><p>The complicated version handle more cases, however this comes at the cost of more indirection and more code artifacts. Prefer to start with a simple solution and refactor to a more complicated one when the time is right.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8e19b2b33c21" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What is a Layer?]]></title>
            <link>https://medium.com/@egonelbre/what-is-a-layer-948bb1a26b5d?source=rss-c01f387bc9f4------2</link>
            <guid isPermaLink="false">https://medium.com/p/948bb1a26b5d</guid>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Egon Elbre]]></dc:creator>
            <pubDate>Thu, 12 Jul 2018 17:47:50 GMT</pubDate>
            <atom:updated>2018-07-13T08:59:01.992Z</atom:updated>
            <content:encoded><![CDATA[<p>This question was bothering me a long time. I mean there are often suggestions for readability such as, don’t mix business and database layer or don’t mix abstraction layers.</p><p>On the surface, it seems like an easy question, and it looks like there are answers to that question:</p><blockquote>In object-oriented design, a layer is a group of classes that have the same set of link-time module dependencies to other modules. In other words, a layer is a group of reusable components that are reusable in similar circumstances. In programming languages, the layer distinction is often expressed as “import” dependencies between software modules. — <a href="https://en.wikipedia.org/wiki/Layer_(object-oriented_design)">Wikipedia</a></blockquote><p>and</p><blockquote>In computing, an abstraction layer or abstraction level is a way of hiding the implementation details of a particular set of functionality, allowing the separation of concerns to facilitate interoperability and platform independence.[snip] An abstraction layer is a generalization of a conceptual model or algorithm, away from any specific implementation. — <a href="https://en.wikipedia.org/wiki/Abstraction_layer">Wikipedia</a></blockquote><p>However, this really doesn’t fully answer the question.</p><ul><li>How would you write a program to detect a layer?</li><li>How would you write a program that detects a mixing of layers?</li><li>Why is mixing layers bad for readability?</li></ul><p>When does database layer transition over into domain layer? Could you write a program that draws the line between layers when they are mixed?</p><p><em>Before proceeding I recommend to think about it a little, because I’m interested in other opinions on it as well.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*fNbhSBQK05H4A8pvJ1AKiQ.png" /></figure><p>My first realization was that there really isn’t a fixed line between layers. It is something which is chosen by a programmer. There is always a gradient from one layer to another. For example Data Access Object is partly related to a domain and partly to a database.</p><p>Considering that there is a gradient from one layer to another, it’s not that surprising that we misclassify things or have trouble classifying. Sometimes these “misclassifications” end up as <a href="https://en.wikipedia.org/wiki/Leaky_abstraction">leaky abstractions</a>, or in other words, things that leak leak hidden implementation details.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*HYSXFFOVjCU9IctsD9Fd7w.png" /></figure><p>This might seem like we are getting further away from a measurable “layer”, but it gives one important insight:</p><blockquote>Layers are a human concern not a technical one.</blockquote><p>Let’s imagine having code which includes both database interaction and some inline-assembly. This is often called mixing of “abstraction layers”. However in an high-performance numeric library, using inline assembly (or <a href="https://en.wikipedia.org/wiki/Intrinsic_function">intrinsics</a>) might be completely fine.</p><p>One of the major reasons to use abstractions is to remove and hide the non-essential. That way we can focus more on the given task at hand.</p><p>In other words, it’s about keeping our locus of attention in a specific place in our code and mental model. The way we think about domain concepts is somewhat different from the way machine works. When we switch between those ways of thinking we are also switching between ideas.</p><p>With the high-performance numeric library using machine level details, such as SIMD, doesn’t add significant mental overhead, because for high-performance you already need to think how the machine operates. Effectively how machine operates is part of high-performance mental model.</p><p>For all intents and purposes, switching between layers has all the same downsides as multitasking.</p><p>We see a layer encouraging:</p><ul><li>mental model cohesion</li><li>code reuse</li></ul><p>Initially we asked how we would detect mixing of layers. Code reuse detection is conceptually not that complicated. When several projects end-up copying the same code with minor differences it can be classified as repeated code.</p><p>How do we detect mental model cohesion? I’m going to suggest using machine learning, which obviously isn’t as easy as I make it sound.</p><p>We could learn a <a href="https://en.wikipedia.org/wiki/Word_embedding">word embedding</a> using books on different topics. For example we could learn the domain of accounting from different laws or books. Then learn things from database books. Learn coding from coding books. In a sense, we could say that mental model cohesion is approximately the same as word distance in books.</p><p>Having learned the embedding, we can see whether the code at hand has terminology from different clustered areas. When a name which is not strongly aligned with the other words in a scope, then it may indicate a bad name, and possibly mixed layers. <em>Of course, there are many tiny things that need to be considered to make this model useful. If you do end up implementing it, I’m definitely interested in the results.</em></p><p>After understanding these concepts, I think <em>layer</em> is a bad name and evokes bad imagery when used to describe the problems.</p><p>I think visualizing these things as bubbles of ideas that we want to keep as clear as possible is more useful than trying to stack things on top of each other. It’s important to note that in reality the classification has many more dimensions than would fit on a single flat image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*P6BJmiUhxbdJu5zjM2AxEA.png" /><figcaption>cohesion of ideas</figcaption></figure><p>There are few important parts to layers / abstractions:</p><ol><li>mental model cohesion</li><li>code reuse</li><li><a href="https://en.wikipedia.org/wiki/Shearing_layers"><em>shearing layers</em></a><em> (which we ignored in this post)</em></li></ol><p>We could also potentially add <em>hiding information</em> as well, but I think that it comes implicitly with <em>mental model cohesion</em>.</p><p>Thinking in terms of cohesive ideas is more vague, however, it makes us notice why we are organizing things in the first place. It gets us closer to visualizing the fundamental forces that created the layers in the first place.</p><p><em>If you found this article useful you can buy me a coffee at </em><a href="https://www.buymeacoffee.com/egon"><em>https://www.buymeacoffee.com/egon</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=948bb1a26b5d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>