<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>PragDave&#39;s Blog</title>
<link>https://pragdave.me/thoughts/</link>
<atom:link href="https://pragdave.me/thoughts/index.xml" rel="self" type="application/rss+xml"/>
<description>On software development, technology, and the occasional brain fart</description>
<image>
<url>https://pragdave.me/assets/images/gnome-header.svg</url>
<title>PragDave&#39;s Blog</title>
<link>https://pragdave.me/thoughts/</link>
</image>
<generator>quarto-1.8.24</generator>
<lastBuildDate>Thu, 26 Sep 2024 05:00:00 GMT</lastBuildDate>
<item>
  <title>A Stateless Object Isn’t an Object</title>
  <link>https://pragdave.me/thoughts/active/2024-09-26-stateless-object-isnt-an-object.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/bad-object.png" class="img-fluid"></p>
</div></div><p>Object orientation has two parents. One was fairly strict; it saw the world in terms of types and abstractions. It viewed objects as being things constructed from classes, getting both their behavior and the shape of their state from the class that created them. Inheritance was used to share behaviour, often in ways that were convenient but baffling: if you had class <code>Person</code> that you wanted to add to a linked list, your make that class a subclass of <code>Link</code>. This parent was called Simula.</p>
<p>The other parent was more of a party animal. Smalltalk was all about the objects: each was effectively an independent process with its own state. The only way to access it was by sending it messages. Objects in Smalltalk were often long-lived (measured in years) bexcause they were permanent residents of something called the <em>image</em>. Everything was inspectable, and everything was open to change. It was an environment for doing things, not thinking about doing them.</p>
<p>It turns out that Simula had the stronger genes: C++, Ada, Java, Swift, and, to some extent, Ruby, all take the stance that classes are the backbone of OO programming.</p>
<section id="its-all-about-state" class="level2">
<h2 data-anchor-id="its-all-about-state">It’s All About State</h2>
<p>The trouble with classes is that they intimately couple state and the functions that manipulate that state. Indeed, this is often heralded as a benefit of the paradigm.</p>
<p>It isn’t.</p>
<p>Managing state is a vital part of programming. But it’s the boring and nonproductive part.</p>
<p>A program is something that <em>transforms</em> data. It takes inputs and produces outputs. It responds to events by changing some state.</p>
<p>Relying on objects makes it more difficult to do this: the coupling of functions and instance data means that every object has two conflicting personalities, one focussed on maintaining the integrity of the state and the other driven to change that state.</p>
</section>
<section id="make-transformations-first-class" class="level2">
<h2 data-anchor-id="make-transformations-first-class">Make Transformations First Class</h2>
<p>Let’s look an some typical OO code. Given an account number, it finds the correctonding customer, and from there finds the active accounts, and sums their balances.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb1-1">balance <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Customer</span></span>
<span id="cb1-2">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.find</span>(account_number)</span>
<span id="cb1-3">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.active_accounts</span>()</span>
<span id="cb1-4">          <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.sum_balance</span>()</span></code></pre></div></div>
<p>This is bread and butter code. But it’s bad code.</p>
<p>The fault lies in the <code>.</code> operator. It invokes the method on its right in the context of the object on its left. When you use it, you have to make sure that the object has that method, and that it does the correct thing. Typically this means that we load our classes with a bunch of convenience methods just to provide the correct object mappings: <code>Customer.find</code> presumably returns a <code>Customer</code> object. The <code>Customer</code> class must then have an <code>active_accounts</code> instance method that returns a new object of class <code>AccountCollection</code> that in turn has an instance method <code>sum_balance</code> that returns a <code>Currency</code> object.</p>
<p>The <code>.</code> operator encourages us to fill our classes with convenience methods simply so that we can write code that reads well.</p>
<p>But let’s forget about that for a minute, and think of our problem not in terms of classes but instead in terms of transformations.</p>
<p>Now our problem looks more like this:</p>
<p><img src="https://pragdave.me/thoughts/assets/transform-chain.png" class="img-fluid"></p>
<p>The boxes represent some part of the state, and the arrows are transformations applied to the state. The account number is transformed into a customer record, which is transformed into a list of accounts, and so on.</p>
<p>In many languages, this process can be expressed directly as a pipeline of operations. Elixir might look like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb2-1">account_number</span>
<span id="cb2-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Customer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>lookup</span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> extract_customer_accounts</span>
<span id="cb2-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> filter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>account_is_active<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> extract_field<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:balance</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> sum</span></code></pre></div></div>
<p>In this code there are no objects; instead we have data structures containing state, and each data structure is processed by a <em>function</em> to produce a new data structure. And, just as important, each of these data structures is immutable.</p>
<p>If you come from an OO background, you’re probably thinking that this is bullshit. It looks like more code, and possibly even lower-level code.</p>
<p>But stop and think about what this means. The functional part of your code is no longer tied to the data. And functions are now independent of each other: no function relies implicitly on the state tucked away in an instance variable by some prior function. Just think how this changes how you can approach testing. And composing code. And sharing. And…</p>
</section>
<section id="so-give-up-objects-and-write-functional-code" class="level2">
<h2 data-anchor-id="so-give-up-objects-and-write-functional-code">So, Give Up Objects and Write Functional Code?</h2>
<p>No.&nbsp;I personally use a middle ground, and it is working really well for me. I still write classes and use objects. By they are no longer the logic of my programs.</p>
<p>I use objects to hold state. The only methods they contain deal directly with setting and validating that state. They may also have a method to return their representation as a string or as JSON, and they might have a copy constructor (see later).</p>
<p>But these objects are immutable: they only reveal state via accessor methods, and they have no interface that changes their state.</p>


</section>

 ]]></description>
  <guid>https://pragdave.me/thoughts/active/2024-09-26-stateless-object-isnt-an-object.html</guid>
  <pubDate>Thu, 26 Sep 2024 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Composable Configuration</title>
  <link>https://pragdave.me/thoughts/active/2024-06-13-configuration-chains.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/gerbil-bucket-brigade.jpg" class="img-fluid"></p>
</div></div><p>I recently found myself trying to manage the configuration of a bunch of utility applications. These apps were extracting data from a database, massaging it, then uploading to to a Graphql server.</p>
<p>I had three databases: local development, staging, and production, and three servers: test, staging and production. I needed to run any of the apps, passing in appropriate URLS and credentials based on the database and server.</p>
<p>It seems that the conventional way is to use config files with approriate names and somehow knit them together. One example of this is <a href="https://github.com/dotenvx/dotenvx">.dotenvx</a>, where you could run</p>
<pre class="session"><code>$ dotenvx run -f .env.db-staging -f .env.gql-test -- ruby ....</code></pre>
<p>Using a tool such as this adds yet more dependencies and a bit more cognative load to an already complex project. So I went primitive and wrote something that lets me do this using a command such as:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># use staging database and test gql server</span></span>
<span id="cb2-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> db-staging gql-test ruby ....</span>
<span id="cb2-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># or the test database and the staging server</span></span>
<span id="cb2-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> db-test gql-staging ruby ...</span></code></pre></div></div>
<section id="embarassing-simplicity" class="level3">
<h3 data-anchor-id="embarassing-simplicity">Embarassing Simplicity</h3>
<p><code>db-staging</code> and <code>gql-test</code> are simply shell scripts that set environment variables. In this case I’m using the <em>fish</em> shell, but this’ll likely work in bash and zsh.<sup>1</sup></p>
<div class="columns">
<div class="column" style="width:45%;">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/opt/homebrew/bin/fish</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> DB_HOST localhost</span>
<span id="cb3-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> DB_PORT 3306</span>
<span id="cb3-5"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> DB_NAME pip</span>
<span id="cb3-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> DB_USERNAME dave</span>
<span id="cb3-7"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> DB_PASSWORD <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"secret"</span></span>
<span id="cb3-8"></span>
<span id="cb3-9"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$argv</span></span></code></pre></div></div>
</div><div class="column" style="width:5%;">

</div><div class="column" style="width:45%;">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/opt/homebrew/bin/fish</span></span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> GQL_SERVER  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://my.server"</span></span>
<span id="cb4-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-x</span> GQL_ACCESS_TOKEN  .....</span>
<span id="cb4-5"></span>
<span id="cb4-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">exec</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$argv</span></span></code></pre></div></div>
</div>
</div>
<p>The only special thing is the last line. After the script sets the configuration into environment variables, it calls <code>exec</code> to invoke the next command on the command line. This command will inherit the environment variables just set. If it’s another configuration script, it can set more variables, and then chain to the next command.</p>
<p>For example, when you run</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> db-staging gql-test ruby ....</span></code></pre></div></div>
<p>the <code>db-staging</code> script receives the arguments <code>gql-test ruby ...</code>. When it calls <code>exec</code>, the <code>gql-test</code> script is run, receiving <code>ruby ...</code> as an argument. This is our application, and it runs with all the configuation we just set up.</p>
<p>And, when it finishes and returns us to our top-level prompt, the variables are no longer in the environment.</p>


</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>You’ll need to change <code>$argv</code> to whatever your shell uses.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <guid>https://pragdave.me/thoughts/active/2024-06-13-configuration-chains.html</guid>
  <pubDate>Thu, 13 Jun 2024 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Never Fear Simple Ideas</title>
  <link>https://pragdave.me/thoughts/active/2023-10-05-minimalism.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/minimalism.png" class="img-fluid"></p>
</div></div><p>I love watching content about music composition and production. One of the more thoughtful of these channels is <a href="https://www.youtube.com/@VenusTheory">Venus Theory</a>, where Cam talks not just about music but also the production (in both senses) of music.</p>
<p>A <a href="https://www.youtube.com/watch?v=8FNmtguAJGETheory">recent video</a> talks about the Minimalist movement in music, but quickly pivots to talking about a <em>minimalist approach</em> to creating music. Why? Because he believes that the reason people often start on a new piece but then never finish it is that they’re overwhelmed by the options available to them. They worry about leaving something behind, about not using every single technique and tool in every piece.</p>
<p>His answer is to define Minimalism not as “having as little as possible” but instead as “only using what you need to express an idea.” In practice, he says, that means “being as intentional as possible.” Make sure there’s a reason for everything you do, and that the reason moves you towards the expression of your idea.</p>
<p>Clearly, this only works if the ideas you have can be expressed minimally, so he also makes the point that you should “never fear the simple idea.”</p>
<section id="software-minimalism" class="level2">
<h2 data-anchor-id="software-minimalism">Software Minimalism</h2>
<p>Of course, every developer knows that this applies to what we do. Everryone knows rgat we start by producing the simplest thing that could work. We never start projects by thinking about tools, frameworks, and libraries.</p>
<p>Do we…</p>


</section>

 ]]></description>
  <guid>https://pragdave.me/thoughts/active/2023-10-05-minimalism.html</guid>
  <pubDate>Thu, 05 Oct 2023 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Regaining Balance: Dreyfus and My Vestibular System</title>
  <link>https://pragdave.me/thoughts/active/2023-09-22-regaining-balance.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/vertigo-spirals.png" class="img-fluid"></p>
</div></div><p>Ten days ago I woke up in the middle of the night with no idea where up or down was; no indication whether I was lying still; or falling; or spinning. My eyes were moving randomly, and I had no balance. In the end, I sat up by closing my eyes, ignoring my feeling of falling, and using my hands to feel where the matress was.</p>
<p>An hour later I was in the emergency room, rapidly depleting their supply of sick bags while they tried to work out what was going on. An MRI revealed I hadn’t had a stroke, and didn’t have a brain tumor, but I did have a “disease” deep in my sinuses.</p>
<p>All that drama, and I had vertigo from a blockage in my vestibular system.</p>
<p>Twelve hours later, the fairground ride had stopped: if I lay still in bed, the world stayed still as well (and I didn’t throw up; always a plus). However, whenever I moved, the world moved too, but the wrong way. Queasy.</p>
<p>The next day I saw a physical therapist who specialized in vestibular stuff. She did what amounted to an extended field sobriety test before coming up with a diagnosis and a plan of action.</p>
<div>
<p><img src="https://pragdave.me/thoughts/assets/brain-tightrope.png" style="float: right; width: 33%; border-radius: 1rem; margin: 0 0 1rem 1rem"> And that plan? We were going to teach my brain how to balance again.</p>
<p>Apparently your brain is constantly calibrating the various balance-related inputs it receives: the horizon your eyes see, the different pressures on your feet, and the inputs from the gyroscopes and accelerometers in your ears. Normally, everything is pretty much in sync, and only minor adjustments need to get made. Sometimes, though, things go out of whack. If you’re on a boat, your eyes, ears, and feet disagree. Your conscious brain knows why, but your real brain gets upset. Sometimes, it decides you must have eaten (or drunk) something that messed with your nervous system, and it makes you try to throw it up.</p>
</div>
<p>And when you get off that boat you may have noticed that, although you’re on solid ground, your body thinks it is still rocking with the waves. You may stumble when you walk, or find yourself closing your eyes to stop the arguments inside your head.</p>
<p>That’s what happened after my incident. My brain recalibrated itself to my faulty vestibular system, updating itself with a whole new set of parameters. So as my feeling returned, my brain was interpreting the signals as if it was still faulty: if I turned my head, or moved my eyes too fast, I’d fall over.</p>
<section id="inner-tennis-inner-ear" class="level1">
<h1>Inner Tennis, Inner Ear</h1>
<div>
<p><a href="https://www.amazon.com/Inner-Game-Tennis-Classic-Performance/dp/0679778314" style="float: right; width: 33%; border-radius: 1rem; margin: 0 0 1rem 1rem"> <img src="https://pragdave.me/thoughts/assets/igt.jpg" width="100%"> </a> When I talk about learning, I often describe a documentary I saw a long time ago about W. Timothy Gallwey’s <em>Inner Game of Tennis</em>. Part of the documentary shows him coaching a woman who had problems with her serve. He put a chair on one side of the net, then positioned the student on the other side with a laundry basket full of balls. Her job was to serve balls, but not aim for the chair. Instead, she had to call out where the ball landed in relation to the chair: behind and to the left, in front, and so on. After a hundred balls, he asked her to start hitting the chair, and she did, just about every time. She’d given her brain feedback on how a particular set of muscle movements related to the impact of the ball.</p>
<p>And that’s what my therapy is. I have a series of exercises where I move combinations of my head, my eyes, and a target held in my hands. I start slow, and speed up until I feel queasy. Just like the tennis player, I’m teaching my brain how to interpret the signals it’s getting from my eyes and ears. As it learns, the disconnect between the two lessens, and I can go faster before having to stop. Eventually, my brain will internalize the meaning of the signals, and I’ll be able to balance without thinking about it.</p>
</div>
</section>
<section id="learning-is-forgetting" class="level1">
<h1>Learning is Forgetting</h1>
<blockquote class="blockquote">
<p>Civilization advances by extending the number of important operations which we can perform without thinking about them <span class="quote-author">Alfred North Whitehead</span></p>
</blockquote>
<p>Tennis and vestibular therapy are both great examples of what it means to learn. When we start out doing something, we have no way to make sense of what we’re seeing. We often have to rely on someone else to interpret it for us: “that message means it can’t find the file” or “you’ll find it easier to turn the wheel if you accelerate coming out of the turn.”</p>
<p>Gradually we internalize all these sensations: we start to build context. We then have a framework which we can use both to store new knowledge and to predict outcomes in novel situations.</p>
<p>After a while, we get to the point where we handle all the low-level stuff without consciously thinking about it: we don’t remember driving to the supermarket, we don’t know why we bounced the ball one extra time before serving, we don’t know <em>why</em> the code we just wrote feels wrong.</p>
<p>The Drefus model of skill acquisition provides a useful model of this process. It describes five stages of learning, starting at <em>Novice</em> where you have to be told what to do and process it using explicit concious thought. At the other end of the spectrum is <em>Expert</em>, where you have internalized the knowledge and can act without thinking about it. As you gain experience, you learn to trust your intuition.</p>
<p>The beginner doesn’t know. The expert doesn’t necessarily know <em>why</em>.</p>
<p>After my little episode, I had to treat my brain as a novice at balancing, showing it explicitly what things felt like while reciting out loud what I was doing. After about a week of this, I’m now at the point where I can do most daily activities without thinking about balance.</p>
<p>So much of what we do, both as developers and as people, relies on this intuition. And we can develop this intuition using conscious execises: doing a thing and telling ourselves what we’re doing.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>A Reprogramming Execise
</div>
</div>
<div class="callout-body-container callout-body">
<p>I’ve never been good at (or particularly liked) Sudoku, so that makes it great playground for experimenting; I’m trying to teach my intuition how to play. I look at a board, say out loud what I’m thinking, then make a move. If it is wrong, I say “wrong” and undo it. If it is right, I say “right.”</p>
<p>I’ve been playing three or four games a day for the last few months. To my surprise, I’m starting to be able to fill in squares without thinking about it. It’s still pretty flaky, but my accuracy feels like it’s improving.</p>
</div>
</div>


</section>

 ]]></description>
  <guid>https://pragdave.me/thoughts/active/2023-09-22-regaining-balance.html</guid>
  <pubDate>Fri, 22 Sep 2023 05:00:00 GMT</pubDate>
</item>
<item>
  <title>In Praise of Maintainers</title>
  <link>https://pragdave.me/thoughts/active/2023-09-21-in-praise-of-maintainers.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/engineer-fixing-something.png" class="img-fluid"></p>
</div></div><p>I love developing software. I love the thrill of the new, the excitement of seeing ideas come to life. I love the feeling of accomplishment when I’ve built something that other people can use. That’s why I release a fair amount of it as open source. It’s fun to see other people take what I created and use and improve it.</p>
<p>However, releasing all that software comes with a cost. People find bugs. People write asking for changes (sometimes demanding changes). People don’t like the way I implement something, or the way I indent the code, and send 500 line pull requests. And the more you release, the more that load builds, and the less time you have to build new stuff.</p>
<p>So I made the decision a long time ago to stop maintaining most of my open source projects. As a result, much of it falls into disuse.</p>
<p>If you look at successful projects, though, you’ll find that they are built on a solid foundation of maintainers. These are the people who invest countless hours making sure the code under their care works with the latest release of X, takes advantage of new standards, and contains as few bugs as possible. Oh, and they’ll be adding new features, too.</p>
<p>This is a massive job, probably dwarfing the original development effort. And it largely goes unsung.</p>
<section id="earmark" class="level3">
<h3 data-anchor-id="earmark">Earmark</h3>
<p>One of the things I do when faced with a new language is to try to implement a basic Markdown parser. Markdown is ugly enough that you have to explore lots of language features to get it right.</p>
<p>When I first learned Elixir, I wrote a Markdown parser that was actually usable, called <a href="https://hexdocs.pm/earmark/Earmark.html">Earmark</a>. It was used early on to format the documentation for Elixir libraries.</p>
<p>After a while, I reached the point where I had to move on, so I asked if anyone would be interesting in taking over the project.</p>
<p>Robert Dober stepped up. This was one of the most fortunate things that have happened to me in my open source career. Robert has not just maintained Earmark; he’s extended it in ways I’d have never imagined. It’s really his project now, not mine. And I’m so grateful for that.</p>
<p>But to my shame, I’ve never publicly thanked Robert for his work. So, as he himself steps down from the project, I want to say “Thank you, Robert, for all the effort and imagination you’ve invested in this software. You’ve made a major difference to the Elixir world, and made things better for developers globally.”</p>
<p>Give a maintainer a hug today. They deserve it.</p>


</section>

 ]]></description>
  <guid>https://pragdave.me/thoughts/active/2023-09-21-in-praise-of-maintainers.html</guid>
  <pubDate>Thu, 21 Sep 2023 05:00:00 GMT</pubDate>
</item>
<item>
  <title>PragProg 2.0</title>
  <link>https://pragdave.me/thoughts/active/2023-09-19-pragprog-2.0.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/pragprog-2.0.png" class="img-fluid"></p>
</div></div><p>Seven years ago, I <a href="../../thoughts/active/2016-05-03-pragdave-2.0.html">announced</a> that I’d be stepping away from the Pragmatic Bookshelf to spend some time playing. I quoted Steve Jobs:</p>
<blockquote class="blockquote">
<p>For the past 33 years, I have looked in the mirror every morning and asked myself: “If today were the last day of my life, would I want to do what I am about to do today?” And whenever the answer has been ‘No’ for too many days in a row, I know I need to change something. <span class="quote-author">Steve Jobs</span></p>
</blockquote>
<p>And play I did. I learned a bunch of new languages, experimented with new techniques and technologies, refined my thinking about learning and software development, and tried really hard to get two pieces of wood to join with no gaps.</p>
<div>
<p><img style="float: right; width: 20%; margin-left: 1em; margin-bottom: 1em;" src="https://pragdave.me/thoughts/assets/gerbil-mirror.png" alt="Gerbil Mirror"> This year, looking in the mirror each morning, I started realizing that there was something I wanted to do more than just play. I wanted to get back involved; I wanted to reclaim the feeling we had when we first started building the Bookshelf, when everything was possible (and most of it seemed unlikely to work).</p>
<p>It turns out that, having stepped back himself a few years ago, Andy was ready to leave altogether, so I stepped in.</p>
<p>What I found was a well oiled machine; an amazing team who worked well, and worked well together. My first priority was to avoid screwing that up.</p>
</div>
<p>It’s also clear that some things just haven’t stood the test of time. We have a website that probably looked fresh in 2004; now it’s little more than a fairly tedious catalog. We’re producing great community content on <a href="https://forum.devtalk.com/search?expanded=true&amp;q=tags%3Apragprog">Devtalk</a> and <a href="https://medium.com/pragmatic-programmers">Medium</a> that deserve a much bigger audience. We’re still producing the best programming books, but I can’t help feeling that we could also deliver this great content in other ways, too.</p>
<p>On the production side, we’re still using a toolchain that is basically unchanged since I left. It produces great looking books, but technology has moved on, and so should we.</p>
<p>One thing I learned in my time away is that I need other people. So, I’m asking for your help. Please, tell me what The Pragmatic Bookshelf can do to improve your life: as a developer, as a content creator, and as a human. And, most importantly, should we bring the gerbils back?</p>
<p>There are several options if you want to get in touch. You can email me at <a href="mailto://improve@pragprog.org">improve@pragprog.org</a>. You can enter comments in the form below. Or you can chat with me directly by <a href="https://calendly.com/pragdave">booking a slot online</a>.</p>
<p>I am really excited to see what we can come up with together.</p>
<p>Thanks</p>
<p>Dave</p>
<hr>
<iframe src="https://docs.google.com/forms/d/e/1FAIpQLSeZvpO6WRuGwu9PflyO8tR9WL4Qnw5v61Yc5WLx_60kMMdNwg/viewform?embedded=true" width="740" height="1000" frameborder="0" marginheight="0" marginwidth="0">
Loading…
</iframe>



 ]]></description>
  <guid>https://pragdave.me/thoughts/active/2023-09-19-pragprog-2.0.html</guid>
  <pubDate>Tue, 19 Sep 2023 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Giving a Talk Over Zoom</title>
  <link>https://pragdave.me/thoughts/active/2022-04-05-giving-a-talk-over-zoom.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/speaking-over-zoom.jpg" class="img-fluid figure-img"></p>
<figcaption>Screenshot of pragdave giving a remote talk</figcaption>
</figure>
</div>
<p>When the pandemic lockdowns started, I was in the middle of teaching a semester-long class on programming languages. I had to start giving my content online. I <em>hated</em> it. I hated that I couldn’t interact with the class. I hated having to juggle different views, switching from slides, to me, to an editor. But most of all, I hated talking while sitting down. Just the act of sitting seemed to drain all the energy out of it.</p>
<p>Since then I’ve been experimenting with different ways of organizing my online speaking environment, and yesterday I think I’ve come close to nailing it.</p>
<section id="video" class="level2">
<h2 data-anchor-id="video">Video</h2>
<p>My video solution is to create slides with a pure black background. I then combine my camera video and the window capture from the slide presentation inside OBS.</p>
<p>I then set up a video filter for the slide channel which basically masks out anything that is black: only the slide foreground appears in the final video. I tried using the green screen filter with a custom color, but I ended up getting better results with a luma key:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/luma-key.png" class="img-fluid figure-img"></p>
<figcaption>Luma key setting to remove black</figcaption>
</figure>
</div>
<p>The next problem was that the slide content was hard to read on the video background. So I added a gray box around the content on the slide, and added a color key filter to OBS to match it and then reduce its opacity. The result (shown at the top of this post) is a semi-transparent gray background for the slide content.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/color-key.png" class="img-fluid figure-img"></p>
<figcaption>Color key setting to fade background</figcaption>
</figure>
</div>
<p>And that’s it. I create slides with the black background and the content enclosed in the gray box. When merged with the camera video, the black disappears and the gray becomes semitransparent. When I don’t want any slide content on the feed, I simply include a blank black slide in the deck.</p>
<p>To start a talk, I bring up the slide presentation on a screen, make sure OBS is connected to both that screen and my camera feed, and then start the OBS virtual camera. I then configure the video source for whatever is being used to broadcast the talk (Zoom, Jitsi, or whatever) to use the OBS feed.</p>
<section id="a-useful-side-effect" class="level3">
<h3 data-anchor-id="a-useful-side-effect">A Useful Side Effect</h3>
<p>I find it hard to look at the camera when speaking, so this time I dug out an old screen I bought for some Raspberry Pi projects a while back. I spent all of 5 minutes making a plywood backer for it, to which I glued a 5/8” nut. I screwed this into an old microphone stand and positioned the screen right above my camera. I plumbed the HDMI into my Macbook, and used that screen as the place I displayed my presentation. Instant notes, instant feedback that I was on the correct slide, and somewhere to focus my eyes.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/monitor-screen.jpg" class="img-fluid figure-img"></p>
<figcaption>The monitor screen</figcaption>
</figure>
</div>
</section>
</section>
<section id="audio" class="level2">
<h2 data-anchor-id="audio">Audio</h2>
<p>I’m still struggling a little with audio. Unfortunately, OBS doesn’t send sound out through its virtual camera device. But only OBS knows the delays it is introducing to the video feed, and so only it can properly synchronize the audio and video. I’m still experimenting with this: currently I’m using VB-Cable to intercept the incoming output, feed it through some processing, and then feed the result as audio input to the video conference software. The results have not been great. The audio sounds fine, but the timing drifts. If anyone has a good way of handling this, I’d love to hear it.</p>


</section>

 ]]></description>
  <category>personal</category>
  <category>teams</category>
  <guid>https://pragdave.me/thoughts/active/2022-04-05-giving-a-talk-over-zoom.html</guid>
  <pubDate>Tue, 05 Apr 2022 05:00:00 GMT</pubDate>
</item>
<item>
  <title>The Interview</title>
  <link>https://pragdave.me/thoughts/active/2022-02-23-the-interview.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/interview.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@charlesdeluvio">charles deluvio</a> on <a href="https://unsplash.com/s/photos/interview?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<style>
.sam, .naiomi, .casey, .casey-vo, .casey-vo-cont {
 margin-left: 5rem;
 margin-top: 2rem;
}

.sam:before {
 content: "SAM";
 font-weight: bold;
 display: block;
 text-align: center;
}

.naiomi:before {
 content: "NAIOMI";
 font-weight: bold;
 display: block;
 text-align: center;
}

.casey:before {
 content: "CASEY";
 font-weight: bold;
 display: block;
 text-align: center;
}

.casey-vo:before {
 content: "CASEY (voiceover)";
 font-weight: bold;
 display: block;
 text-align: center;
}

.casey-vo-cont:before {
 content: "CASEY (voiceover continued)";
 font-weight: bold;
 display: block;
 text-align: center;
}
</style>
<p><b>EXT. STREET - DAYTIME</b></p>
<p><b>FADE IN:</b></p>
<p>We’re looking through the top of a tree at a second-floor window of a townhouse. It’s obviously springtime: the tree has blossoms, and the leaves are small and bright green. Through the window we see movement and the light turns off.</p>
<p>[CAMERA pans down to front door level. CASEY opens door. CAMERA pans to follow her down to street level, then pans horizontally, keeping her in profile, as she walks.]</p>
<p>CASEY looks confident.</p>
<p><b>TITLES: The Interview</b></p>
<p>Titles play over montage: walking, wait for bus, in bus, walking, signing it at office reception, elevator.</p>
<p>Titles end.</p>
<p><b>INT. OFFICE - DAYTIME</b></p>
<p>Casey sits across from Sam, about to start a job interview. She is sure of her skills, and excited to prove them.</p>
<div class="sam" data-markdown="1">
<p>Good morning, Ms Jones. Welcome to Snippts.</p>
</div>
<div class="casey" data-markdown="1">
<p>Thank you. I’m really excited to be here; it’s such a well respected company. I’m looking forward to showing you what I can do. And, please, call me Casey.</p>
</div>
<div class="sam" data-markdown="1">
<p>OK, Casey. I’m Sam. Let me give you a little background on Snippts before we start the technical part of the interview.</p>
<p>We’re coming up on our 15th anniversary, and we’ve been laser-focussed on our mission for each of those years: we make developer’s lives easier by delivering snippets of code they need.</p>
<p>I’ll just fill you in a little bit on our origin story. Our founder was typing code one day when she discovered she’d accidentally created a routine that reversed the elements of an array without using any extra memory. She was so excited she mentioned it at the next local Java user group. The next day she was contacted by eleven different local companies who wanted to buy the code.</p>
</div>
<div class="casey" data-markdown="1">
<p>That’s unbelievable!</p>
</div>
<div class="sam" data-markdown="1">
<p>Yup. And she realised that if this one routine was marketable, there must be others that were in demand. And so Snippts was born.</p>
<p>We now have over 200 developers in 12 countries, working night and day to produce small but significant pieces of code for the world’s biggest companies.</p>
</div>
<div class="casey" data-markdown="1">
<p><em>(Trying to sound enthusiastic and make a good impression)</em></p>
<p>That’s amazing, Sam! So, what’s a typical project?</p>
</div>
<div class="sam" data-markdown="1">
<p>Great question! Let me tell you about just a few of the projects that we signed in the last week.</p>
<p>A household name in dishwashers needs a snippet that finds the longest sequence of repeating characters in a string. A European government needs code that converts a number in Roman numerals to binary. And our linked list division is always buzzing: this week we had a big pharma company commission us to find the middle element of a list, and an aerospace company asked us for code to determine if a linked list is a palindrome.</p>
</div>
<div class="casey" data-markdown="1">
<p>Wow! You’re really busy, and with cool-sounding work. I’m really excited; I’ve been doing this kind of stuff for years. I’m an expert at coding 15-line algorithms. Where do I sign?</p>
</div>
<div class="sam" data-markdown="1">
<p>Well, before we get to that stage, you’ll need to take our standard technical entrance test. I know, with your experience, you’ll probably ace it, but…</p>
</div>
<div class="casey" data-markdown="1">
<p><em>(Gearing up to show off her technical skills)</em></p>
<p>Sure, I understand. Bring it on.</p>
</div>
<div class="sam" data-markdown="1">
<p>OK. Here we go. First question: What’s the square root of 3152?</p>
</div>
<div class="casey" data-markdown="1">
<p><em>(Surprised, reaching for her phone)</em></p>
<p>Hang on…</p>
</div>
<div class="sam" data-markdown="1">
<p>Stop! No phones, laptops, or calculators. This job requires that you use numbers, so we need to make sure you can work with them.</p>
</div>
<div class="casey-vo" data-markdown="1">
<p><em>(She looks startled at first, but smiles by the end of v/o)</em></p>
<p>What on earth? Oh, he must want to know if I can calculate square roots.</p>
</div>
<div class="casey" data-markdown="1">
<p>Umm… I could write some code that used Newton-Raphson to calculate it, but I’ve never felt need to to calculate square roots in my head; I’ve always got my phone or computer nearby.</p>
</div>
<div class="sam" data-markdown="1">
<p>So you’re saying you don’t know?</p>
</div>
<div class="casey" data-markdown="1">
<p><em>(Scrambling to remember High School Math)</em></p>
<p>Oh, no, hang on. Fifty squared is 2,500, and 60 squared is 3,600, so the answer is in the middle. Fifty-five squared is 50 squared plus 2 times 50 times 5, plus 25, which is… uh… 2500 plus 500 plus 25: 3025. That’s pretty close, I’m guessing the answer is somewhere around 56.</p>
</div>
<div class="sam" data-markdown="1">
<p><em>(Displeased)</em></p>
<p>Guessing? Pretty close? I was hoping for better, Ms Jones. OK, moving on. Grab that keyboard and get into an editor.</p>
<p>Now, look at the whiteboard. See that extract from&nbsp;Miss Manners’ Guide to Office Etiquette?&nbsp;It’s 150 words long. I need you to type it into your editor without looking at your keyboard, and take less than 2 minutes to do it.</p>
</div>
<div class="casey" data-markdown="1">
<p>OK, I don’t see why this a relevant, but I can do that: I touch type at 90 words per minute.</p>
</div>
<div class="sam" data-markdown="1">
<p>That’s fantastic. We use keyboards here. A lot. The faster you type, the more productive you are. But you didn’t let me finish. Before you interrupted me, I was going to add the last part of the test: You need to use your left hand to type on the right hand side of the keyboard, and your left hand on the right side. Ready?</p>
</div>
<div class="casey" data-markdown="1">
<p>Whoa! Wait! What on earth does this have to do with how well I can write snippets for you?</p>
</div>
<div class="sam" data-markdown="1">
<p>I already explained: typing speed equals productivity.</p>
</div>
<div class="casey" data-markdown="1">
<p>I’d debate that, but whatever. But swapping left and right?</p>
</div>
<div class="sam" data-markdown="1">
<p>We want to see how adaptable you are. Sometimes clients want a snippet that sorts results in ascending order, and other times the sneaky devils ask for descending. Can you imagine? Anyway, that keeps us on our toes, and our staff need to be able to cope with the unexpected. One, two, three…</p>
</div>
<p>(SAM clicks stopwatch)</p>
<p>(After some obvious thought, CASEY picks up the keyboard and rotates it 180 degrees so the space bar is away from her. She then starts pecking out the words.)</p>
<div class="sam" data-markdown="1">
<p>Stop. Stop! What are you doing? I told you that you should use your left hand on the right side of the keyboard and vice versa, but your arms aren’t crossed.</p>
</div>
<div class="casey" data-markdown="1">
<p><em>(Losing confidence as she goes on and sees that he’s serious)</em></p>
<p>Well… You just said I should have my left hand on the right side and my right hand on the left…. Rather than try to type with my arms crossed, I thought I’d just…. flip the keyboard around.</p>
</div>
<div class="sam" data-markdown="1">
<p>Hmmm… That might be technically correct, but it’s not what I wanted you to do. I clearly wanted you to cross your arms. You won’t fit in here if you don’t learn to work out what you boss wants, and not just what they say they want. Frankly, I’m a little disappointed. But, just for the sake of completeness, let’s do the last coding test. Let’s look at Quicksort.</p>
</div>
<p>(CASEY perks up)</p>
<div class="sam" data-markdown="1">
<p>What is Quicksort’s time complexity?</p>
</div>
<div class="casey" data-markdown="1">
<p><em>(Confident, smiling) </em></p>
<p>Well, Quicksort is typically O(n log n), but it can degrade to O(n²) with some input data sets.</p>
</div>
<div class="sam" data-markdown="1">
<p>So which is it: O(n log n) or O(n²)?</p>
</div>
<div class="casey" data-markdown="1">
<p>Ah, well, it’s both. Um… and neither. Any single answer would be misleading.</p>
</div>
<div class="sam" data-markdown="1">
<p>I’m sorry, Ms Jones. That kind of muddy thinking just doesn’t work around here. When our customers ask our sales team for a snippet, they expect to be told how it will perform. They expect, and we give them, a single value. Anything else would make us look like we don’t know what we’re doing.</p>
<p>I’m sorry, but I don’t think this is going to work out. Thank you for your time. Pick up a T-shirt on the way out.</p>
</div>
<div class="cut">
FADE THRU BLK:
</div>
<p><b>EXT. SIDEWALK - DAYTIME, RAINING</b></p>
<p>We’re back on the street we started from. It’s a rainy autumn day; leaves are turning and colors are muted.</p>
<p>[CAMERA starts from where we cut away on opening shot, and pans back to CASEY’s front door, then up to the original window, then in through the window to…</p>
<p><b>INT. CASEY’s LIVING ROOM</b></p>
<p>CASEY is sitting on the sofa wearing a worn SNIPPTS T-shift. Her flatmate, NAIOMI, is gently pacing.</p>
<div class="naiomi">
<p>C’mon, Case. It’s almost six. If we leave it any longer there’ll only be veggie pizza left.</p>
</div>
<div class="casey">
<p>Nah. I’m going to skip it this time. All they ever talk about at the Elixir user group is technical stuff. And I’ve got an interview tomorrow. I’ve got more important things to think about than code if I’m going to get a job.</p>
</div>
<div class="naiomi">
<p><em>(exasperated)</em></p>
<p>You’ve been working on this for six months. All that typing with your hands crossed—looks cool ’n all, but… And, come on: who cares what the square root of 3173 is?</p>
</div>
<div class="casey">
<p><em>(instantly)</em> 56.33 to two decimal places.</p>
<p>But I still need to work on my decisiveness. Every question has one answer. I’m staying here and preparing.</p>
<p>Have fun.</p>
</div>
<p>NAIOMI leaves, shaking her head.</p>
<p>CASEY is on the sofa, eyes closed and scrunched in concentration.</p>
<div class="casey">
<p><em>(speaking to self)</em></p>
<p>O log n.&nbsp;No, O n squared. No, log n, No…</p>
</div>
<p><b>FADE OUT</b></p>



 ]]></description>
  <category>programming</category>
  <category>recruiting</category>
  <guid>https://pragdave.me/thoughts/active/2022-02-23-the-interview.html</guid>
  <pubDate>Wed, 23 Feb 2022 06:00:00 GMT</pubDate>
</item>
<item>
  <title>Learning a New Language (or anything, really…)</title>
  <link>https://pragdave.me/thoughts/active/2020-05-05-advice-on-learning-a-language.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/brett-jordan-uPWvYb07JXs-unsplash.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@brett_jordan?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Brett Jordan</a> on <a href="https://unsplash.com/s/photos/learn?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<p>One of my students emailed me privately. She wanted to learn a new language over the summer, but she has <em>“always had trouble finding structure and knowing what to learn when pursuing independent studies such as these.”</em> I’ve had this same question a number of times in the past, so I thought it might be useful to post my response.</p>
<p>This is just my way of thinking about it. I’d be interested to hear your techniques for picking up new things.</p>
<blockquote class="blockquote">
<p>I do a fair amount of woodworking. It’s one of those hobbies where you are constantly tempted by bright, shiny new tools. When I first started, I fell into that trap, and bought a lot of stuff I never really used. So I have a rule: now I only invest in a tool if I have a current, real need for it. That way I can guarantee that when it arrives I will actually use it. And, by using it, I’ll get to learn it so I’ll know when I can apply it later.</p>
<p>I think it is the same with all tools. So when it comes to learning a new language, my advice is always: find a thing you want to do. It doesn’t have to be a major project; in fact it’s probably better if it isn’t. Look for something that would be useful, not vital. Maybe something that would help with a hobby, or a group that you belong to. Something that could be solved in hundreds, not thousands, of lines of code.</p>
<p>Then choose some aspect of it. Something you understand in terms&nbsp;of requirements. Prototype it in the new language. Know going in that you’ll waste a couple of days just getting familiar with the tooling. Don’t try for finished code, but explore. It’ll be frustrating, because you’ll have to keep stopping to look things up, and because you’ll constantly realize that what you just wrote could be written better. Understand that this is the entire point of learning. It’s not about getting things right. It’s about getting things wrong and gaining experience from that.</p>
<p>At the end of maybe a week, throw all that code away and start again. You’ll find that you’ll be able to knock out the same functionality that took a week in maybe a couple of hours, and you’ll feel that it is better code.&nbsp;</p>
<p>At this point you’ll feel that you’re finally getting it, and you’ll start to feel productive. Keep digging into the language and tooling. Keep challenging yourself.&nbsp;</p>
<p>There’ll come a time when suddenly it feel like you’ve hit a wall; stuff stops being easy, and you begin to doubt that you actually do understand it. This happens to everyone learning something new. It’s a manifestation of the fact that you have now internalized enough of the language that you find yourself making decisions based on not “how can I make this work?” but rather on “what’s a good way to make this work?”. This point is a bit like earning a black belt in the martial arts. This is when it starts being fun!</p>
</blockquote>



 ]]></description>
  <category>improving</category>
  <category>programming</category>
  <category>training</category>
  <guid>https://pragdave.me/thoughts/active/2020-05-05-advice-on-learning-a-language.html</guid>
  <pubDate>Tue, 05 May 2020 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Where Does State Live?</title>
  <link>https://pragdave.me/thoughts/active/2019-01-10-where-does-state-live.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/jan-antonin-kolar-lRoX0shwjUQ-unsplash.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@jankolar?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jan Antonin Kolar</a> on <a href="https://unsplash.com/s/photos/filing?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<p>Several people have questioned my description of when you should use dynamic components:</p>
<blockquote class="blockquote">
<p>Does your component maintain state across multiple calls, and do you need multiple versions of that state? For example, are you representing a user session, or the state of games being played? If so, use a dynamic component, where each component maintains state for the session/game/….</p>
</blockquote>
<p>Their objection is that I need to add the word <em>shared</em>, so that you only need dynamic components to share data.</p>
<p>It’s an interesting point of view, and it took me a while to work out their reasoning. Now that I understand it, I’m still sticking my my statement, but I’d like to explain both points of view.</p>
<section id="recap-dynamic-components" class="level3">
<h3 data-anchor-id="recap-dynamic-components">Recap: Dynamic Components</h3>
<p>A dynamic component represents a server factory. You ask the factory for a new server, and then use that server until you’re done with it. Being a server, it can maintain its own state.</p>
<section id="lets-use-hangman-as-an-example" class="level4">
<h4 data-anchor-id="lets-use-hangman-as-an-example">Let’s Use Hangman as an Example</h4>
<p>Say you’re implementing a game of hangman.</p>
<p>We’ll agree up front to make the game a separate component: that is, we’ll do</p>
<pre><code>$ mix new game</code></pre>
<p>and write the game logic in this new directory tree.</p>
<p>We’ll write various clients for the game (a command line line, a Phoenix client, and so on).</p>
<p>The game itself has state (the word to be guessed, letters guessed so far, and so on). It also has an API that reveals an external version of that state.</p>
<p>Each game being played needs its own state.</p>
<p>The debate is about where that state should be held.</p>
</section>
<section id="their-perspective-on-this" class="level4">
<h4 data-anchor-id="their-perspective-on-this">Their Perspective on This</h4>
<p>Some folks argue that each client has exactly one game. Although the client will be a process, there’s no need for the game to be one: the client can hold the game’s state, passing it in on each call to the game API and updating it on each return from the API. The client code might look something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> play_game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-2">  game <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> %<span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Hangman</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">State</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Hangman</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>choose_word_to_guess</span>
<span id="cb2-3">  accept_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-5"></span>
<span id="cb2-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> accept_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-7">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">IO</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>puts <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"The word so far: </span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">#{</span>game<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>word_so_far<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb2-8">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">IO</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>puts <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Letters used: </span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">#{</span>game<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>letters_guessed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>join<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb2-9">  guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> get_next_letter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb2-10">  game  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Hangman</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game, guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-11">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-12">   game<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>won <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> game<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>lost <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb2-13">    handle_end_of_game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-14">   game<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>good_guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb2-15">    handle_good_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game, guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-16">   <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb2-17">    handle_bad_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game, guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-18">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-19"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>Spiffing!</p>
</section>
</section>
<section id="my-perspective" class="level2">
<h2 data-anchor-id="my-perspective">My Perspective</h2>
<p>I’m really nervous about the client having unfettered access to the state of the game. I’m not worried about cheating. I’m concerned because the state is really to do with the <em>implementation</em> of the game. And the implementation of a module should be no ones business but the module’s.</p>
<p>In the code above, the client assumes that the game state contains a string, <code>word_so_far</code> representing the current state of the guess, and that it contains an enumerable, <code>letters_guessed</code> of the guesses so far.</p>
<p>Maybe when we first wrote it, both were true.</p>
<p>But maybe things changed in the game. We decided to change the way we record guesses—say we use a bitmap instead. And maybe we no longer keep a version of the word so far: we can always reconstruct it from the target word and the guesses.</p>
<p>Both of these things are internal implementation issues, but both changes break the client.</p>
<p>This is coupling, and on a larger scale this is a major reason changing code is difficult,</p>
<p>If processes in Elixir were expensive, I would 100% agree with this approach. But they’re not. Instead, developer time is a significant cost, and in particular the time spend maintaining and changing code. So I’m prepared to take the hit of having an extra process lying around if it makes the life of future-me easier.</p>
<p>So my approach would be to turn the game from being as library into being a server. It keeps its game state totally hidden from the outside world: all the rest of the world gets to see is a PID and an API.</p>
<p>The client might look something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb3-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">alias</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Hangman</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">as:</span> H  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 'cos I'm lazy</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> play_game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-4">  game <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> H<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>create<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb3-5">  accept_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb3-7"></span>
<span id="cb3-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> accept_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-9">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">IO</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>puts <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"The word so far: </span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">#{</span>H<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>word_so_far<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb3-10">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">IO</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>puts <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Letters used: </span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">#{</span>H<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>letters_guessed<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Enum</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>join<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb3-11">  guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> get_next_letter<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb3-12">  result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Hangman</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>score_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-13">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">cond</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-14">   result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>won <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>lost <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb3-15">    handle_end_of_game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-16">   result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>good_guess <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb3-17">    handle_good_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game, guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-18">   <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-19">    handle_bad_guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>game, guess<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-20">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb3-21"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>Not much different, really. But now the internal state is opaque, and it’s only made available via API calls. If we change the internal implementation, we can keep the same API, and therefore not break anything.</p>
<p>So, because of this, I’m a big fan of encapsulating state inside processes, even if it isn’t technically necessary.</p>
<p>And that’s what I use Dynamic components for.</p>
<p>As always, I’m looking forward to some interesting comments and perspectives.</p>


</section>

 ]]></description>
  <category>elixir</category>
  <category>functional</category>
  <category>programming</category>
  <guid>https://pragdave.me/thoughts/active/2019-01-10-where-does-state-live.html</guid>
  <pubDate>Thu, 10 Jan 2019 06:00:00 GMT</pubDate>
</item>
<item>
  <title>Elixir Project Structure</title>
  <link>https://pragdave.me/thoughts/active/2018-06-02-project-structure.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/xiong-yan-l7HysfP9BPU-unsplash.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@slothxbear?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Xiong Yan</a> on <a href="https://unsplash.com/s/photos/scaffold?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<p>I think the way we organize our projects’ files obscures the code and make simple things complex. We do it not because we want to, but because we feel we need to in order to tame complexity. there’s another way: stop writing complex code.</p>
<!-- more -->
<section id="the-smoking-guns" class="level3">
<h3 data-anchor-id="the-smoking-guns">The Smoking Guns</h3>
<p>Here’s the result of running <code>mix new my_app --sup</code>:</p>
<pre class="tightlines"><code>"my_app"
├── config
│   └── config.exs
├── lib
│   ├── "my_app"
│   │   └── application.ex
│   └── "my_app.ex"
├── mix.exs
├── README.md
└── test
    ├── "my_app_test.exs"
    └── test_helper.exs</code></pre>
<p>Here’s a Ruby project created with <code>bundle gem my_app</code>:</p>
<pre class="tightlines"><code>"my_app/"
├── bin
│&nbsp;&nbsp; ├── console
│&nbsp;&nbsp; └── setup
├── Gemfile
├── lib
│&nbsp;&nbsp; ├── "my_app"
│&nbsp;&nbsp; │&nbsp;&nbsp; └── version.rb
│&nbsp;&nbsp; └── "my_app.rb"
├── "my_app.gemspec"
├── Rakefile
└── README.md</code></pre>
<p>Here’s a JavaScript project:</p>
<pre class="tightlines"><code>├── dist
│   ├── app.js
│   └── index.html
├── node_modules
├── src
│   ├── lib
│   │   ├── login.js
│   │   └── user.js
│   ├── app.js
│   └── index.html
├── gulpfile.js
├── package.json
└── README</code></pre>
<p>And here’s the recommended Go project tree:</p>
<pre class="tightlines"><code>"project-layout/"
├── api
│&nbsp;&nbsp; └── README.md
├── assets
│&nbsp;&nbsp; └── README.md
├── build
│&nbsp;&nbsp; ├── ci
│&nbsp;&nbsp; ├── package
│&nbsp;&nbsp; └── README.md
├── cmd
│&nbsp;&nbsp; ├── README.md
│&nbsp;&nbsp; └── "_your_app_"
├── configs
│&nbsp;&nbsp; └── README.md
├── deployments
│&nbsp;&nbsp; └── README.md
├── docs
│&nbsp;&nbsp; └── README.md
├── examples
│&nbsp;&nbsp; └── README.md
├── githooks
│&nbsp;&nbsp; └── README.md
├── init
│&nbsp;&nbsp; └── README.md
├── internal
│&nbsp;&nbsp; ├── app
│&nbsp;&nbsp; │&nbsp;&nbsp; └── "_your_app_"
│&nbsp;&nbsp; ├── pkg
│&nbsp;&nbsp; │&nbsp;&nbsp; └── "_your_private_lib_"
│&nbsp;&nbsp; └── README.md
├── LICENSE.md
├── Makefile
├── pkg
│&nbsp;&nbsp; ├── README.md
│&nbsp;&nbsp; └── "_your_public_lib_"
├── README.md
├── scripts
│&nbsp;&nbsp; └── README.md
├── test
│&nbsp;&nbsp; └── README.md
├── third_party
│&nbsp;&nbsp; └── README.md
├── tools
│&nbsp;&nbsp; └── README.md
├── "vendor"
│&nbsp;&nbsp; └── README.md
└── web
    ├── app
    ├── README.md
    ├── static
    └── template</code></pre>
<p>Let’s look at just the top level directory of each:</p>
<table>
<tbody><tr>
<th>
Elixir
</th>
<th>
Ruby
</th>
<th>
JavaScript
</th>
<th>
Go
</th>
</tr>
<tr valign="top">
<td>
<pre class="tightlines"><code>my_app
├── config
├── lib
├── mix.exs
├── README.md
└── test</code></pre>
</td>
<td>
<pre class="tightlines"><code>"my_app/"
├── bin
├── Gemfile
├── lib
├── "my_app.gemspec"
├── Rakefile
└── README.md</code></pre>
</td>
<td>
<pre class="tightlines"><code>├── dist
├── "node_modules"
├── src
├── gulpfile.js
├── package.json
└── README</code></pre>
</td>
<td>
<pre class="tightlines"><code>"project-layout/"
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── init
├── internal
├── LICENSE.md
├── Makefile
├── pkg
├── README.md
├── scripts
├── test
├── third_party
├── tools
├── vendor
└── web</code></pre>
</td>
</tr>
</tbody></table>
<p>Now let’s imagine we can find an alien, unsullied by the preconceptions and practices of us developer folk. Let’s call this individual Normal Human Being.</p>
<p>We show these structures to Normal and ask “what’s going on here?” Normal thinks about this for a while.</p>
<p>“Well,” they say, “I imagine that you organize your thinking hierarchically <em>(how quaint)</em> and that you put the most important things at the top level. Doing things this way means that you can then split each top-level important thing into subthings at the next level in your hierarchy.”</p>
<p>“So, based on what I see across this selection of programming languages, you’re showing me four projects where the most important thing about the code is the boilerplate housekeeping. Clearly, you must be seriously advanced if this trumps the actual code that you write.”</p>
<p>Once they realized that they were wrong, and that, yes, we do worship housekeeping, the NHBs invaded the planet, conquering us without a shot being fired (largely because we were still waiting for NPM install to run on the fire control computers).</p>
</section>
<section id="first-choose-the-correct-problem" class="level3">
<h3 data-anchor-id="first-choose-the-correct-problem">First, Choose The Correct Problem</h3>
<p>I believe the reason for these baroque structures is simple: in the past we learned that when we write complex applications, things got out of hand. We ended up with directories with random names, some containing hundreds of files, each project different from the others.</p>
<p>So we fixed the wrong problem.</p>
<p>We said, “if we impose a strict structure on our projects, we can tame this complex katamari damacy of files.”</p>
<p>But what we <em>should</em> have said was, “let’s not write such big projects.”</p>
</section>
<section id="break-it-down" class="level3">
<h3 data-anchor-id="break-it-down">Break It Down</h3>
<p>Imagine if instead we could build our code using lots of individual components, and that each component could fit into a single source file of (at most) a couple of hundred lines.</p>
<p>What would the project directory tree look like then?</p>
<pre class="tightlines"><code>├── "my_app.ex"    &lt;- "source of component".
├── meta.yml       &lt;- "dependencies, build options, etc".
└── "tests/"</code></pre>
<p>The README is simply the leading comment block in the source file. The build tool uses the metadata to find and resolve dependencies, compile the source, and construct an executable. For a component with no dependencies that followed the default conventions of the language, and which used doctests, the component could be as simple as:</p>
<pre class="tightlines"><code>└─ "my_app.ex"    &lt;- all we need</code></pre>
</section>
<section id="you-may-say-im-bikeshedding" class="level3">
<h3 data-anchor-id="you-may-say-im-bikeshedding">You May Say I’m Bikeshedding</h3>
<p>And I am. Project directory structure is definitely not a big problem.</p>
<p>But the fact that we had to invent these structures, which hide the actual code of our project two, three, or more levels deep in a directory tree, is a smoking gun. We are writing all our code in a single project; a single application. The lessons of the <a href="https://www.somethingsimilar.com/2012/07/23/monorail/">monorail</a> seem to have been forgotten. Frameworks such as Phoenix encourage you to bundle application logic into the web serving codebase. Deployment tools make it simpler to release monolithic applications. And coupling between components only increases.</p>
</section>
<section id="you-may-say-im-a-dreamer" class="level3">
<h3 data-anchor-id="you-may-say-im-a-dreamer">You May Say I’m A Dreamer…</h3>
<p>…but I am experimenting with possible solutions. I’m working on a proof of concept library that makes it easier to write distributed, concurrent components in Elixir. I’m playing with a tool that makes it easier to assemble these components into deliverable solutions, and to deploy those assemblies to a dynamic cloud of machines. It’s way too early to say I have a solution to any of this. But I do have something I can experiment with.</p>
<p>I gave a talk about this at <a href="http://empex.co/events/2018/conference.html">Empex</a> last month.</p>
<iframe width="960" height="540" src="https://www.youtube.com/embed/6U7cLUygMeI" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen="">
</iframe>
<p>Things have changed even since then. But I’m still convinced we need to rethink how we write code.</p>


</section>

 ]]></description>
  <category>elixir</category>
  <category>go</category>
  <category>javascript</category>
  <category>programming</category>
  <category>ruby</category>
  <guid>https://pragdave.me/thoughts/active/2018-06-02-project-structure.html</guid>
  <pubDate>Sat, 02 Jun 2018 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Splitting APIs, Servers, and Implementations in Elixir</title>
  <link>https://pragdave.me/thoughts/active/2017-07-13-decoupling-interface-and-implementation-in-elixir.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/frank-mckenna-tjX_sniNzgQ-unsplash.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@frankiefoto?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">frank mckenna</a> on <a href="https://unsplash.com/s/photos/container?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<blockquote class="blockquote">
<p>tldr; I think the conventional way of structuring Elixir code could be improved by paying more attention to decoupling.</p>
</blockquote>
<p>I just finished writing the first of my Coding Gnome courses. This one was an <a href="https://codestool.coding-gnome.com">introduction to Elixir</a> for experienced programmers.</p>
<p>I tried to concentrate on partitioning code in a reasonable manner. I didn’t use the traditional Elixir scheme, which comes from a mating of Ruby and Erlang project layouts. Instead, I tried to come at it with a fresh eye, asking myself how the various aspects of the code could best be decoupled.</p>
<section id="separating-execution-strategy-from-logic" class="level2">
<h2 data-anchor-id="separating-execution-strategy-from-logic">Separating Execution Strategy from Logic</h2>
<p>Elixir and Erlang have an interesting execution module. You program using processes and message passing, but they abstract this into the concept of <em>servers</em>. You call a function (typically <code>GenServer.call(pid, args)</code>) and this in turn send a message to the server identified by <code>pid</code>. Inside that server, you write callback functions that are invoked in response to these messages.</p>
<p>In real life, no one wants to use a server whose API involves such convolution. So the convention arose that you’d provide an API layer to your server, written in the same module. Here’s an example, stolen from the Elixir guide, and cut down somewhat:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defmodule</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">KV</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Registry</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-2">  <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">use</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span></span>
<span id="cb1-3"></span>
<span id="cb1-4">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">##############</span></span>
<span id="cb1-5">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Client API #</span></span>
<span id="cb1-6">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">##############</span></span>
<span id="cb1-7"></span>
<span id="cb1-8">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> start_link <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-9">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>start_link<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">__MODULE__</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:ok</span>, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-10">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-11"></span>
<span id="cb1-12">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> lookup<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>server, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-13">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>call<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>server, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:lookup</span>, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb1-14">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-15"></span>
<span id="cb1-16">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>server, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-17">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>call<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>server, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:store</span>, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb1-18">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-19"></span>
<span id="cb1-20">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">####################</span></span>
<span id="cb1-21">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Server Callbacks #</span></span>
<span id="cb1-22">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">####################</span></span>
<span id="cb1-23">  </span>
<span id="cb1-24">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> init<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:ok</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-25">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:ok</span>, %<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{}}</span></span>
<span id="cb1-26">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-27"></span>
<span id="cb1-28">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> handle_call<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">({</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:lookup</span>, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>, _from, names<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-29">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:reply</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>fetch<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>, names<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-30">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-31"></span>
<span id="cb1-32">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> handle_call<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">({</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:store</span>, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>, _from, names<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-33">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:reply</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)}</span></span>
<span id="cb1-34">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-35"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>Here the top half of the module is the public facing API, and the lower half is the code that runs in a separate process and that implements the functionality.</p>
<p>I’ve never been comfortable with this. It seems to bury the important part—the actual implementation—in amongst all kinds of GenServer housekeeping. It also makes the development of the code a lot trickier—you have to write the server at the same time that you write the implementation.</p>
<p>So in the course I recommended a different approach—one that I’ve been using personally for a while. In it, I write the application functionality in its own module, under <code>lib/</code>. This has no GenServer support—after all, it’s just the app logic.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defmodule</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># in lib/kv/impl.ex</span></span>
<span id="cb2-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> new<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-3">    %<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb2-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-5"></span>
<span id="cb2-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> lookup<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-7">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>fetch<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-8">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-9"></span>
<span id="cb2-10">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-11">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-12">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>That makes it easier to see what’s going on. I can also write tests directly against this logic.</p>
<p>Now, here’s the weird part. You might look at this and say that here’s the module that other applications should call. But I think that’s not the case. Let’s instead declare the API in the top-level <code>kv.ex</code> file:</p>
<pre class="tightlines"><code>lib
├── kv
│&nbsp;&nbsp; └── impl.ex
└── kv.ex       ("the API belongs in here")</code></pre>
<p>Right now, this API just calls directly down to the implementation.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defmodule</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb4-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defdelegate</span> new<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span>,                     <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">to:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span></span>
<span id="cb4-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defdelegate</span> lookup<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,       <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">to:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span></span>
<span id="cb4-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defdelegate</span> store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">to:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span></span>
<span id="cb4-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>Also pretty clean, right?</p>
<p>So now we have a working application (aka library), and people can start using it.</p>
<section id="bring-on-the-server" class="level3">
<h3 data-anchor-id="bring-on-the-server">Bring On the Server</h3>
<p>Circumstances change, and our library needs to become a full server.</p>
<p>We write the server code in <code>lib/server.ex</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defmodule</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Server</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb5-2">  <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">use</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span></span>
<span id="cb5-3">  <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">alias</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span></span>
<span id="cb5-4"></span>
<span id="cb5-5">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> init<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb5-6">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:ok</span>, store <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb5-8"></span>
<span id="cb5-9">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> handle_call<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">({</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:lookup</span>, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>, _, store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb5-10">    result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>lookup<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>store, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-11">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:reply</span>, result, store <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-12">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb5-13"></span>
<span id="cb5-14">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> handle_cast<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">({</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:store</span>, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span>, store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb5-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:noreply</span>, <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Impl</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>store, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-16">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb5-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>This is just pure server code—no API, and no application logic.</p>
<p>Finally, we change the API in the top-level <code>kv.ex</code> file:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defmodule</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> new<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:ok</span>, names <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>start_link<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Kv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">Server</span>, %<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{})</span></span>
<span id="cb6-4">    names</span>
<span id="cb6-5">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb6-6">  </span>
<span id="cb6-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> lookup<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-8">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>call<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:lookup</span>, name<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb6-9">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb6-10">  </span>
<span id="cb6-11">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> store<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, name, value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-12">    <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">GenServer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>cast<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>names, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:store</span>, name, value <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb6-13">    names</span>
<span id="cb6-14">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb6-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>The only slightly strange thing is that <code>store()</code> returns the server pid. Doing so maintains the same API that we had previously, where the <code>store()</code> function returned the updated map. In both cases, the return value simply represents an (opaque) updated state.</p>
<p>As a result, we now have:</p>
<pre class="tightlines"><code>lib
├── kv
│&nbsp;&nbsp; ├── impl.ex     ("Application implementation")
│&nbsp;&nbsp; └── server.ex   ("GenServer implementation")
└── kv.ex           (API)</code></pre>
<p>This is the scheme I now use, and so far I much prefer it to the conventional one.</p>
</section>
</section>
<section id="bonus-section" class="level2">
<h2 data-anchor-id="bonus-section">Bonus Section</h2>
<section id="subservers" class="level3">
<h3 data-anchor-id="subservers">Subservers</h3>
<p>What if my application needs its own GenServers as part of its implementation? Well, just follow the same pattern, but one level down the directory tree:</p>
<pre class="tightlines"><code>lib
├── kv
│&nbsp;&nbsp; ├── bucket
│&nbsp;&nbsp; │&nbsp;&nbsp; ├── impl.ex
│&nbsp;&nbsp; │&nbsp;&nbsp; └── "server.ex"
│&nbsp;&nbsp; ├── bucket.ex
│&nbsp;&nbsp; ├── impl.ex
│&nbsp;&nbsp; └── "server.ex"
└── kv.ex</code></pre>
<p>The rule here is that no one outside the application is allowed to call functions outside <code>lib/kv.ex</code>.</p>
</section>
<section id="applications-are-components" class="level3">
<h3 data-anchor-id="applications-are-components">Applications are Components</h3>
<p>Although the good folks who brought us Erlang were really, really smart people who produced designs for a future that did not yet exist, they really weren’t that good at naming things.</p>
<p>One of the most confusing names is <em>application</em>.</p>
<!-- TODO: <ThinkificPreview id="127256"/> -->
<p>In “the real world” an application is something you deliver to the end user. A payroll system is an application. A word processor is an application.</p>
<p>But in Erlang, and hence Elixir, an application is a self-contained bundle of modules and resources with its own lifecycle. The Logger, for example, is an application. The Elixir compiler contains over a dozen.</p>
<p>Erlang applications are really just components.</p>
<p>But because the word application is so ingrained in us developers, it is hard to remember this. And so we have a tendency to throw all our code into a single project tree because, after all, it’s the application.</p>
<p>So I’m trying to retrain my brain by writing my code as series of separate applications, each as small as I can make it. And I’m not using umbrella projects for this, because I want to be able to share these components across different projects. Instead, I just use file dependencies.</p>
<p>So, next time you’re writing a killer Phoenix app, think about why you have Ecto in your web tier. Shouldn’t the business logic be out in its own application? And why do you have contexts in the web layer? Maybe the contexts each correspond to an external app.</p>
<p>Decouple. You know it makes sense.</p>


</section>
</section>

 ]]></description>
  <guid>https://pragdave.me/thoughts/active/2017-07-13-decoupling-interface-and-implementation-in-elixir.html</guid>
  <pubDate>Thu, 13 Jul 2017 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Testing Private Functions</title>
  <link>https://pragdave.me/thoughts/active/2017-03-31-tesing-private-functions.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/robot-opening-safe.jpg" class="img-fluid figure-img"></p>
<figcaption>A cute robot in a safe</figcaption>
</figure>
</div>
<p>A couple of days ago, I published a <a href="https://hex.pm/packages/private">trivial little Elixir library</a> that temporarily overrides the <code>private</code> status of functions while running tests.</p>
<p>I thought it was useful. I tend to decompose my work into lots of functions, and try to publicly expose only those that I want to be part of a module or class’s API. But I often want to test some particular aspect of the nonpublic functions. To do that, I’ve had to set up a suitable environment for the public APIs to ensure my private function gets called the way I want it to be called, and then work out how to tell from the public API whether it worked. This is indirect and laborious, so much so that I often just gave in and made the internal functions public.</p>
<p>In Ruby, there are cheats that let you invoke private methods. In Elixir, there aren’t. Hence my little library. It that changes the visibility of functions if they are being compiled for the purpose of running tests.</p>
<p>So far so good. I’m personally using this library every day, and my code seems clearer because of it.</p>
<p>But then I started getting comments. Not many, but they all seemed to share the same misconception. “You can’t test a private function! That’s an implementation detail. You can only test the public API.”</p>
<p>I think this is a common belief. Let me explain why I feel it is wrong.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/keep_out.jpg" class="img-fluid figure-img"></p>
<figcaption>Keep out sign. DimitryB via <a href="https://www.flickr.com/photos/dimitryb/2280688546/in/photolist-4tx8fi-6L8CS7-7VTJSs-6EPhxA-6LEHD7-8NZ7RT-ndsW2-bJFW3-48wVFF-a7BJni-64uShN-49S72Z-a8WRPg-47n3as-48HTde-53ryB-dRXinh-o8zwPT-fHtHaP-8jw9Da-6KVZoZ-7MtWt3-owVaNf-5sPCe-T8rQSR-dCktbn-q7Mhfe-d56mS3-7DGs9E-8GQmsA-2D2sP-bkcH1D-dckmub-c6vSLS-ueTK-dUappy-7YquPv-5zjHF3-5gpHg8-5TYnwx-65uMcs-9nMoJo-r6SVPi-nKMfpx-naCBq3-8JS7R7-atwQai-dLoRCZ-aAsmFJ-paRyfq">Flickr</a></figcaption>
</figure>
</div>
<section id="what-is-a-private-function" class="level3">
<h3 data-anchor-id="what-is-a-private-function">What is a private function?</h3>
<p>A private function (or method) is one that can only be called from inside the module (or class) that defines it. It is invisible as far as the rest of the code is concerned.</p>
</section>
<section id="why-do-we-need-them" class="level3">
<h3 data-anchor-id="why-do-we-need-them">Why do we need them?</h3>
<p>A module is a collection of functions that share a common purpose: working out sales tax, interfacing to Twitter, creating a chord progression, and so on. The rest of the code in an application calls functions in a module when it needs that module’s expertise. For example, a Twitter module will have functions to send a tweet, read a tweet, and maybe subscribe to a timeline. The functions that do this are part of the modules external interface—its API.</p>
<p>The API functions are public. They are exposed to the rest of the app.</p>
<p>But an API function could be doing a complex job. So we would want to split it up into a number of subfunctions. These will typically be written in the same module. You can think of them as the <em>implementation</em> of the API.</p>
<p>Logically, they’re just functions. We can define them just as we define the API functions. But there’s a problem. Other people may read our code and see that, as well as the “official” API, we expose all these helper functions. And maybe one or two of these might be useful in their code. So they call them.</p>
</section>
<section id="so-what-if-someone-calls-my-helper-functions" class="level3">
<h3 data-anchor-id="so-what-if-someone-calls-my-helper-functions">So what if someone calls my helper functions?</h3>
<p>Imagine it’s a month later, and you realize that you could improve the implementation of the module you wrote. You get stuck in, rip out half the code and replace it with new stuff.</p>
<p>Now, you don’t want to change your API—other people depend on that. But you feel totally free to change any of the helpers. After all, they’re just there to implement the API. After to finish hacking, you make sure your API passes its tests, and publish your masterpiece.</p>
<p>Thirty seconds later the emails start arriving: “You broke my code.” People who (wrongly) relied on the internal implementation of your module suddenly found that the functions they use had disappeared, or had changed.</p>
<p>Their code was coupled to the internal implementation of yours.</p>
<p><img src="https://pragdave.me/thoughts/assets/tangled_seaweed.jpg" class="img-fluid" alt="Tangled seaweed. Quinn Dombrowski via Flickr. [CC BY-SA 2.0]">{:.wide}</p>
</section>
<section id="why-is-coupling-bad" class="level3">
<h3 data-anchor-id="why-is-coupling-bad">Why is coupling bad?</h3>
<p>To my mind, there is only one rule when it comes to designing software:</p>
<blockquote class="blockquote">
<p>Given the choice between two alternatives, choose the one that makes future change easier</p>
</blockquote>
<p>Most of the principles of good design are just someone’s idea of how to codify some aspect of this.</p>
<p>Avoiding unnecessary coupling is one of those principles.</p>
<p>If thing Y depends on thing Z, then changes to thing Z affect thing Y. Even worse, if X depends on Y, then a change to Z might force a change to Y which then breaks X. And, to make it a total disaster, dependencies aren’t nice and linear like this. Instead, they form a complex mesh. In a bad (typical?) code base, these dependency chains can often interconnect the majority of the code.</p>
<p>The problem is that a change to any module in such a system has the potential to ripple through to every other part of the system. Change the calling sequence of a function, and potentially dozens of other modules will need to change, too. This is the software equivalent to the butterfly flapping its wings in Tokyo. It’s chaos. And it makes it hard (and stressful) to change code.</p>
</section>
<section id="whats-this-got-to-do-with-private-functions" class="level3">
<h3 data-anchor-id="whats-this-got-to-do-with-private-functions">What’s this got to do with private functions?</h3>
<p>Every time you code a call from module A to a function in module B, you set up a dependency between them. A becomes coupled to B.</p>
<p>That’s not a bad thing. The whole reason you write code is to have it be called. But you try to arrange things so that when you write a module you provide a public API, which you expect people to call, and a private implementation, which is none of their business.</p>
<p>In the old days, this was never actually enforced. You wrote comments saying <code>one()</code>, <code>two()</code>, and <code>three()</code> are the public API, and you’d have some kind of banner comment saying</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode c code-with-copy"><code class="sourceCode c"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**************************************************/</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*  The low-level implementation follows...       */</span></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**************************************************/</span></span></code></pre></div></div>
<p>Then language designers wised up, and added visibility modifiers. You could declare that the functions that formed your module’s API were publicly available, and the rest were private. Now you were free to change the internals, safe in the knowledge that, as long as you didn’t change the API, nothing would break as a result of your refactoring.</p>
</section>
<section id="whats-this-got-to-do-with-testing" class="level3">
<h3 data-anchor-id="whats-this-got-to-do-with-testing">What’s this got to do with testing?</h3>
<p>Nothing.</p>
<p>And that’s the point.</p>
<p>If I feel the need to test a piece of code, I want to isolate that code as much as I can. This lets my tests focus on just the thing they’re testing. Sure, I want to test my APIs. But I also want to isolate and test pieces of the implementation, too.</p>
</section>
<section id="doesnt-that-mean-your-tests-may-fail-if-you-change-the-implementation" class="level3">
<h3 data-anchor-id="doesnt-that-mean-your-tests-may-fail-if-you-change-the-implementation">Doesn’t that mean your tests may fail if you change the implementation?</h3>
<p>Of course.</p>
</section>
<section id="but-then-you-cant-refactor" class="level3">
<h3 data-anchor-id="but-then-you-cant-refactor">But then you can’t refactor</h3>
<p>Says who? Seriously.</p>
<p>Refactoring encourages you to change the implementation without changing the API. It suggests using tests to verify this. Those tests shouldn’t fail at the end of each step of refactoring. But they may well fail <em>during</em> the refactoring.</p>
<p>So if <em>they</em> can fail, then so can the tests that I write on my private implementation functions. The only difference is that the API tests act as proxies for the rest of the application. You shouldn’t change them—the same tests should run identically against the pre- and post-refactored code.</p>
<p>The tests of the implementation are volatile. If you break them, it could be because they are now testing the wrong thing. It’s perfectly OK to change these to reflect the changes to the implementation.</p>
</section>
<section id="the-point" class="level3">
<h3 data-anchor-id="the-point">The point?</h3>
<ul>
<li><p>It’s good to decompose complex functions into smaller ones. Ideally each function has just one responsibility.</p></li>
<li><p>It’s good to differentiate the stuff that shouldn’t change (your public interface) from the stuff that may change (your internal implementation). Making the implementation private makes this easier.</p></li>
<li><p>You should test code at both the API level and at the granular level. Visibility modifiers make the latter nearly impossible. Hence the Private library.</p></li>
</ul>


</section>

 ]]></description>
  <category>programming</category>
  <guid>https://pragdave.me/thoughts/active/2017-03-31-tesing-private-functions.html</guid>
  <pubDate>Fri, 31 Mar 2017 05:00:00 GMT</pubDate>
</item>
<item>
  <title>We Perform State</title>
  <link>https://pragdave.me/thoughts/active/2017-01-19-we-perform-state.html</link>
  <description><![CDATA[ 





<p><img src="https://pragdave.me/thoughts/assets/we_perform_state.jpg" class="img-fluid"></p>
<p>I saw this sign over the weekend.</p>
<p>It seems to be a definition of object-orientation…</p>



 ]]></description>
  <category>programming</category>
  <category>silly</category>
  <guid>https://pragdave.me/thoughts/active/2017-01-19-we-perform-state.html</guid>
  <pubDate>Thu, 19 Jan 2017 06:00:00 GMT</pubDate>
</item>
<item>
  <title>Pragdave 2.0</title>
  <link>https://pragdave.me/thoughts/active/2016-05-03-pragdave-2.0.html</link>
  <description><![CDATA[ 






<div class="no-row-height column-margin column-container"><div class="">
<p><img src="https://pragdave.me/thoughts/assets/gnome-smiling.svg" class="img-fluid"></p>
</div></div><blockquote class="blockquote">
<p>For the past 33 years, I have looked in the mirror every morning and asked myself: “If today were the last day of my life, would I want to do what I am about to do today?” And whenever the answer has been ‘No’ for too many days in a row, I know I need to change something.</p>
<p><span class="quote-author">Steve Jobs</span></p>
</blockquote>
<p>After almost 20 years working with Andy as <em>The Pragmatic Programmers</em>, and after 15 of those years publishing stuff with <em>The Pragmatic Bookshelf</em>, I’ve decided it’s time for a change.</p>
<p>I have a lot of pride in the stuff we achieved over those years.</p>
<ul>
<li><p>We wrote <em>The Pragmatic Programmer</em>. It started life as a pet project, which somehow ended up getting published, and which still surprises me by selling well so many years later.</p></li>
<li><p>We created a new kind of publishing company, founded on the classic phrase “how hard could it be?” Well, we found out. And along the way, we discovered that good practices such as continuous builds, automation, DRY, version control, and small iterations work just as well when creating books as they do in software development.</p></li>
<li><p>I wrote our publishing toolchain (three times). From markdown or XML to PDF, print, epub, and mobi, with automated code inclusion, embedded indexing, smart cross referencing, and an extensible plugin system, our system lets authors focus on the content, while we can push betas straight from the same repository they are working in.</p></li>
<li><p>Talking about betas, I think we created a number of trends in tech publishing. My memory is notoriously flaky, but I think we pioneered a number of innovations:</p>
<ul>
<li><p>distribution of DRM-free PDF copies of all our books</p></li>
<li><p>availability of DRM-free epub and mobi versions of all our titles</p></li>
<li><p>automated delivery of books and updates to Dropbox, Google Drive, and (until Amazon blocked it) Kindle devices</p></li>
<li><p>the beta book concept, where ebooks are continuously updated as the author writes new content</p></li>
<li><p>the living book concept, where new editions were heavily discounted (or free) to owners of the prior edition</p></li>
</ul></li>
</ul>
<p>Looking outward, I think that the stuff we did has had an impact on the life of developers.</p>
<p><em>The Pragmatic Programmer</em> has added to our vocabulary, with DRY, tracer bullets, broken windows, and the like.</p>
<p><em>Programming Ruby</em> introduced this amazing language to the English-speaking world, and <em>Agile Web Development with Rails</em> helped kickstart a web revolution.</p>
<p>More recently, <em>Programming Elixir</em> and the Phoenix book are again changing the way we think about programming servers on the web.</p>
<p>That said, I think that I really take the most pride in the more human side of it.</p>
<section id="the-people" class="level2">
<h2 data-anchor-id="the-people">The People</h2>
<p>Over these 20 years, I’ve been blessed to work with and learn from a vast number of amazing people. The dedication and skill of everyone at the Bookshelf—Janet, Susannah, the editors, and everyone else—continues to amaze me. The effort and enthusiasm of our authors is stunning. And the loyalty of our hundreds of thousands of readers is humbling.</p>
</section>
<section id="why-the-change" class="level2">
<h2 data-anchor-id="why-the-change">Why the Change?</h2>
<p>Deep in my soul, I’m a programmer. Given a free choice, I create code, write or speak about code, or sit chatting about code.</p>
<p>At the Bookshelf, I’ve written tons of code—the online systems, the book production toolchain, and a bunch of other stuff. But I also do a lot of grown-up stuff, like meetings, marketing, accounting, and so on. And it feels like personally I’m seeing diminishing returns from this.</p>
<p>This year I turn 60. I’m feeling like I probably have one, maybe two, new adventures in me. And I just knew that if I stayed where I was, I’d be comfortable, but I’d be thinking wistfully about what might have been.</p>
<p>I talked about this with Andy last year, and in January I finally reached the decision. He has been fantastic since then as we work to extract my fingers from the various pies that make up the Bookshelf.</p>
<p>I’m not abandoning the bookshelf—I’m still an owner, and will be working with Andy as needed. I’m just moving away from the day-to-day stuff.</p>
</section>
<section id="what-next" class="level2">
<h2 data-anchor-id="what-next">What Next?</h2>
<div class="half-right">
<p><img src="https://pragdave.me/thoughts/assets/play-gnome.png" class="img-fluid"></p>
</div>
<p>I honestly don’t know. That’s exciting.</p>
<p>I <em>do</em> know that I will be teaching a credit class on Elixir and real-world development at SMU this fall. I also want to start creating a different kind of content for some tutorial ideas I have.</p>
<p>I now have more time to attend and speak at conferences, workshops, and so on. One of the great joys in my life is the set of people who I considered to be good friends even though we only meet stroboscopically at conferences around the world. We meet in Amsterdam and continue a conversation we started in Bangalore three months earlier. I’m looking forward to seeing them more often.</p>
<p>I’m also looking forward to doing more advisory and consulting work. I really enjoy looking at problems from a different angle and coming up with surprising solutions (and I’m actually quite good at it).</p>
<p>In the meantime, I’m doing what I love to do—playing with new languages, tools, techniques, and ideas.</p>
<p>I’ll continue to be pragdave. I’m just pushing a new release or two….</p>
<p>Keep up with me at <a href="https://pragdave.me">pragdave.me</a>.</p>
<p>And remember to make it fun!</p>


</section>

 ]]></description>
  <category>bookshelf</category>
  <category>personal</category>
  <guid>https://pragdave.me/thoughts/active/2016-05-03-pragdave-2.0.html</guid>
  <pubDate>Tue, 03 May 2016 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Personal Area Stereo</title>
  <link>https://pragdave.me/thoughts/active/2015-08-06-personal-area-stereo.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/david-pisnoy-UJUgBnemP7o-unsplash.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@davidpisnoy?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">David Pisnoy</a> on <a href="https://unsplash.com/s/photos/piano?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<p>I like listening to music while working. But I don’t like wearing headphones—after a while they start feeling claustrophobic.</p>
<p>After a little experimentation, I’ve come up with something that works well for me. I have music that sounds almost as immersive as using headphones, but at the same time is local to the chair where I work.</p>
<p>The setup uses a pair of Micca COVO-S bookshelf speakers (currently about $50 on <a href="http://www.amazon.com/Micca-COVO-S-Compact-Bookshelf-Speakers/dp/B00N8265I8">Amazon</a>). I made stands for these using a couple of 5lb barbell weights from a sporting goods store, two pieces of threaded iron conduit, and four pipe flanges. I bolted the bottom flange to the weight, and used screws to attach the top flange into the speaker base, separating it from the flange using grommets. (I did this to isolate them a little—I have no idea if it is necessary). The speaker wire runs up through the pipe.</p>
<p>Here’s what they look like:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/speaker-detail.png" class="img-fluid figure-img"></p>
<figcaption>Speaker on stand</figcaption>
</figure>
</div>
<p>I use a Topping TP-30 class T Amplifier/USB DAC combination (about $60-70), and a Sony SA-W2500 subwoofer (about $100).</p>
<p>The two Micca speakers are placed next to my chair, facing inwards. The subwoofer and amp sit next to it. I plug my MacBook into the amp using USB or via a cheap bluetooth audio receiver.</p>
<p>The chair-of-work looks like this:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/chair-of-work.jpg" class="img-fluid figure-img"></p>
<figcaption>Chair with speakers</figcaption>
</figure>
</div>
<p>The result sounds surprisingly good. The little Miccas have good detail and fairly flat response from the low-mids up. The subwoofer fills in the rest.</p>
<p>And the good thing for my family is that the sound is surprisingly localized. Sitting it the chair, I get an immersive experience. But get up to fetch a cup of tea, and the sound is just a mild background.</p>



 ]]></description>
  <category>music</category>
  <category>personal</category>
  <guid>https://pragdave.me/thoughts/active/2015-08-06-personal-area-stereo.html</guid>
  <pubDate>Thu, 06 Aug 2015 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Proud to be an American</title>
  <link>https://pragdave.me/thoughts/active/2014-11-25-proud-to-be-an-american.html</link>
  <description><![CDATA[ 





<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://pragdave.me/thoughts/assets/samuel-branch-ZPVisr0s_hQ-unsplash.jpg" class="img-fluid figure-img"></p>
<figcaption>Photo by <a href="https://unsplash.com/@sbranch?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Samuel Branch</a> on <a href="https://unsplash.com/s/photos/flag?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>
</div>
<p>Twenty five years ago, I was an English software developer working on a project for a large US company. I’d traveled down to Atlanta with the project leader. We had a Sunday night free, so we went up to Stone Mountain to see the show.</p>
<p>Back then, the show was a <em>son et lumière</em>, projected onto the massive north face of the mountain, a face that contains a bas relief of three confederate heroes: Jackson, Lee, and Davis. The show was rousing and impressive event (with an engagingly southern perspective on history). It ended with a resounding rendition of <em>God Bless the USA</em>. That’s the song with the chorus that starts <em>I’m proud to be an American…</em>. As a Brit, I found myself with tears in my eyes. To quote Marc Cohn, “Ma’am, I am tonight.”</p>
<p>Six months later I married that project leader, and she moved to England. Five years after that, we moved to the States, where we raised our two boys, started a consulting-company-turned-publisher, and generally settled down.</p>
<p>I’ve now lived here longer than anywhere else. The USA is my home. So today I finished up the process of naturalization—I’m now a US citizen.</p>
<p>And, during the ceremony, they played a montage video. And, yes, the background music was Lee Greenwood singing, <em>God Bless the USA</em>. And I stood there, tearing up again, thinking about those 25 years.</p>
<p>I’ve lived in many countries. I’ve liked each in turn. But this is where I choose to be now. It’s a country of people who have chosen to be here. It makes mistakes, then tries to fix them. It comes across as brash, but the people have subtlety and charm. It has the energy of youth, along with the accompanying inexperience. It’s a place where things can get done, and often redone. It’s a glorious, chaotic, Great Dane puppy of a country.</p>
<p>And, today, I’m proud to be an American.</p>



 ]]></description>
  <category>personal</category>
  <guid>https://pragdave.me/thoughts/active/2014-11-25-proud-to-be-an-american.html</guid>
  <pubDate>Tue, 25 Nov 2014 06:00:00 GMT</pubDate>
</item>
<item>
  <title>Thinking in Transforms—Handling Options</title>
  <link>https://pragdave.me/thoughts/active/2014-10-05-thinking-in-transforms-handling-options.html</link>
  <description><![CDATA[ 





<p><img src="https://pragdave.me/thoughts/assets/butterfly.jpg" class="img-fluid"></p>
<p>I’ve been thinking a lot about the way I program recently. I even gave a talk about it at the first <a href="http://elixirconf.com/">ElixirConf</a>.</p>
<p>One thing I’m discovering is that transforming data is easier to think about than maintaining state. I bumped into an interesting case of this idea when adding option handling to a library I was writing.</p>
<section id="dirwalkersome-background" class="level3">
<h3 data-anchor-id="dirwalkersome-background">DirWalker—Some Background</h3>
<p>I’m working on an app that helps organize large numbers of photos (about 3Tb of them). I needed to be able to traverse all the files in a set of directory trees, and do it lazily. I wrote a GenServer where the state is a list of the paths and files still be be traversed, and the main API returns the next <em>n</em> paths found by traversing the input paths. The code that returns the next path looks something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-2">  stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stat!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>type <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:directory</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb1-5">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-6">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:regular</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb1-7">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-8">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">true</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb1-9">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-10">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>So, if the next file in the list of paths to scan is a directory, we replace it with the list of files in that directory and call ourselves. Otherwise if it is a regular file, we add it to the result and call ourselves on the remaining paths. (The actual code is more complex, as it unfolds the nested path lists, and knows how to return individual paths, but this code isn’t the point of this post.)</p>
</section>
<section id="the-real-world-intrudes" class="level3">
<h3 data-anchor-id="the-real-world-intrudes">The Real World Intrudes</h3>
<p>Having added my DirWalker library to Hex.pm, I got a feature request—could it be made to return the <code>File.Stat</code> structure along with the path to the file?</p>
<p>I wanted to add this capability, but also to make it optional, so I started coding using what felt like the obvious approach:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, opts, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-2">  stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stat!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>type <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:directory</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb2-5">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-6">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:regular</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb2-7">    return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-8">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb2-10">      path</span>
<span id="cb2-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-12">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-13">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">true</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb2-14">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-15">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>So, the function now has nested conditionals—never a good sign—but it is livable-with.</p>
<p>Then I thought, “while I’m making this change, let’s also add an option to return directory paths along with file paths.” And my code explodes in terms of complexity:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, opts, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-2">  stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stat!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>type <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:directory</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb3-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_dir_names <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-6">      return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-8">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-9">        path</span>
<span id="cb3-10">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb3-11">      next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-13">      next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb3-15">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:regular</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb3-16">    return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb3-17">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-18">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-19">      path</span>
<span id="cb3-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb3-21">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-22">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">true</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb3-23">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-24">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb3-25"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</section>
<section id="moose-lends-a-paw" class="level3">
<h3 data-anchor-id="moose-lends-a-paw">Moose Lends a Paw</h3>
<p>So, lots of duplication, and the code is pretty much unreadable. Time to put down the keyboard and take Moose for a walk.</p>
<p>As it stands, the options map represents some state—the values of the two options passed to the API. But we really want to think in terms of transformations. So what happens if we instead think of the options as transformers?</p>
<p>Let’s look at the <code>include_stat</code> option first. If set, we want to return a tuple containing a path and a stat structure; otherwise we return just a path. The first case is a function that looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> path, stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span> path, stat <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>and the second case looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> path, _stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> path <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>So, if the <code>include_stat</code> value in our options was one of these two functions, rather than a boolean value, our main code becomes simpler:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, opts, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-2">  stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stat!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>type <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:directory</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb6-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_dir_names <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb6-6">      return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-7">      next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb6-9">      next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb6-11">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:regular</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb6-12">    return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-13">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-14">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">true</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb6-15">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-16">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb6-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>We can do the same thing with <code>include_dir_names</code>. Here the two functions are</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>and</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>_path, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> result <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>and now our main function becomes:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, opts, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb9-2">  stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stat!<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>type <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb9-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:directory</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb9-5">    return_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-6">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_dir_names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-7">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span>files_in<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> rest<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>, return_value<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-8">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:regular</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb9-9">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> opts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>include_stat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-10">  <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">true</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span></span>
<span id="cb9-11">    next_path<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>rest, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-12">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb9-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>Changing the options from being simple state into things that transform values according the the <em>meaning</em> of each option has tamed the complexity of the <code>next_path</code> function.</p>
<p>But we don’t want the users of our API to have to set up transforming functions—that would force them to know our internal implementation details. So on the way in, we want to map their options (which are booleans) into our functions.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode elixir code-with-copy"><code class="sourceCode elixir"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> setup_mappers<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>opts<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb10-2">  %<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-3">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">include_stat:</span></span>
<span id="cb10-4">      one_of<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>opts<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:include_stat</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>,</span>
<span id="cb10-5">             <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, _stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> path         <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb10-6">             <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span>path, stat<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>,</span>
<span id="cb10-7">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">include_dir_names:</span></span>
<span id="cb10-8">      one_of<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>opts<span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">:include_dir_names</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span>,</span>
<span id="cb10-9">             <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>_path, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> result            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span>, </span>
<span id="cb10-10">             <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fn</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>path, result<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span>  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> result <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb10-13"></span>
<span id="cb10-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">defp</span> one_of<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(</span>bool, if_false, if_true<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb10-15">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> bool, <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">do:</span> if_true, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>: if_false</span>
<span id="cb10-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<p>If you’re interested in all the gritty details, the code is <a href="https://github.com/pragdave/dir_walker/blob/master/lib/dir_walker.ex">in Github</a>.</p>
</section>
<section id="my-takeaway" class="level3">
<h3 data-anchor-id="my-takeaway">My Takeaway</h3>
<p>I wrote my first OO program (in Simula) back in 1974 (which is probably before most Elixir programmers were born—sigh). During the intervening years, I’ve developed many reflexes that made object-oriented development easier. And now I’m having to rethink that tacit knowledge.</p>
<p>Programming in Elixir encourages me to move away from state and to think about transformations. As I force myself to apply this change in thinking at all levels of my code, I discover interesting and delightful new patterns of development.</p>
<p>And that’s why I’m still having a blast, hacking out code, after all these years.</p>


</section>

 ]]></description>
  <category>elixir</category>
  <category>programming</category>
  <guid>https://pragdave.me/thoughts/active/2014-10-05-thinking-in-transforms-handling-options.html</guid>
  <pubDate>Sun, 05 Oct 2014 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Tony Benn’s Five Questions for the Powerful</title>
  <link>https://pragdave.me/thoughts/active/2014-03-14-tony-benns-questions-for-those-in-power.html</link>
  <description><![CDATA[ 





<p>Tony Benn was a British Labour politician. When I was growing up, he was rarely off the news—he was typically to the left of his colleagues, and was not reticent to shame them if he felt they were not toeing a socialist line. And he was popular—he was a member of parliament for half a century.</p>
<p>On the occasion of his death, I came across his “Five Questions to ask the Powerful.” They come from a speech he gave to the House of Commons in 2001:</p>
<div class="half-right">
<p><img src="https://pragdave.me/thoughts/assets/Tony_Benn2.jpg" class="img-fluid"></p>
<div class="overlay-cite">
<p>By I, <a href="//commons.wikimedia.org/w/index.php?title=User:Isujosh&amp;action=edit&amp;redlink=1" class="new" title="User:Isujosh (page does not exist)">Isujosh</a>, <a href="http://creativecommons.org/licenses/by-sa/3.0/" title="Creative Commons Attribution-Share Alike 3.0">CC BY-SA 3.0</a>, <a href="https://commons.wikimedia.org/w/index.php?curid=2436433">Link</a></p>
</div>
</div>
<blockquote style="font-size: 140%" class="blockquote">
<p>If one meets a powerful person—Adolf Hitler, Joe Stalin or Bill Gates–ask them five questions:</p>
<ul>
<li>What power have you got?</li>
<li>Where did you get it from?</li>
<li>In whose interests do you exercise it?</li>
<li>To whom are you accountable?</li>
<li>And how can we get rid of you?</li>
</ul>
</blockquote>
<p>It strikes me that these are questions everyone should ask themselves from time to time. And maybe public figures—from police to judges to politicians—should be asked to publish their answers when assuming office. Of course, the answers will be rote, but at least they will serve as a baseline for their future actions.</p>



 ]]></description>
  <category>personal</category>
  <category>responsibility</category>
  <guid>https://pragdave.me/thoughts/active/2014-03-14-tony-benns-questions-for-those-in-power.html</guid>
  <pubDate>Fri, 14 Mar 2014 05:00:00 GMT</pubDate>
</item>
<item>
  <title>Agile is Dead (Long Live Agility)</title>
  <link>https://pragdave.me/thoughts/active/2014-03-04-time-to-kill-agile.html</link>
  <description><![CDATA[ 





<p>Thirteen years ago, I was among seventeen middle-aged white guys who gathered at Snowbird, Utah. We were there because we shared common beliefs about developing software, and we wondered if there was a way to describe what we believed.</p>
<p>It took less than a day to come up with a short list of values. We published those values, along with a list of practices, as the <a href="http://agilemanifesto.org/">Manifesto for Agile Software Development</a>:</p>
<div data-markdown="1" style="font-size: 120%">
<p>|—:|:–|:—| | <strong>Individuals and Interactions</strong> | over | Processes and Tools | | <strong>Working Software</strong> | over | Comprehensive Documentation | | <strong>Customer Collaboration</strong> | over | Contract Negotiation, and | | <strong>Responding to Change</strong> | over | Following a Plan |</p>
</div>
<p>I was proud of what we did, both the process we followed and the result it produced. And I think that the existence of the manifesto has helped developers break free some some of the wasteful and soul-destroying practices of the ’80s and ’90s.</p>
<p>However, since the Snowbird meeting, I haven’t participated in any Agile events,<sup>1</sup> I haven’t affiliated with the Agile Alliance, and I haven’t done any “agile” consultancy. I didn’t attend the 10th anniversary celebrations.</p>
<p>Why? Because I didn’t think that any of these things were in the spirit of the manifesto we produced. Having conferences about agility is not too far removed from having conferences about ballet dancing, and forming an industry group around the four values always struck me as creating a trade union for people who breathe.</p>
<p>And, unfortunately, I think time has proven me right. The word “agile” has been subverted to the point where it is effectively meaningless, and what passes for an agile community seems to be largely an arena for consultants and vendors to hawk services and products.</p>
<p>So I think it is time to retire the word “Agile.”</p>
<p>I don’t think anyone could object to a ban on the word when it is used as a noun. That’s just plain wrong. “Do Agile Right” and “Agile for Dummies” are just two of the innumerable attacks on the English language featuring the word. They are meaningless. <em>Agile</em> is not a noun, it’s an adjective, and it must qualify something else. “Do Agile Right” is like saying “Do Orange Right.”</p>
<p>But, beyond the grammar problem, there’s a bigger issue. Once the Manifesto became popular, the word <em>agile</em> became a magnet for anyone with points to espouse, hours to bill, or products to sell. It became a marketing term, coopted to improve sales in the same way that words such as <em>eco</em> and <em>natural</em> are. A word that is abused in this way becomes useless—it stops having meaning as it transitions into a brand.</p>
<p>This hurts everyone, but I’m particularly sensitive to the damage it does to developers. It isn’t easy writing code, and developers naturally are on the lookout for things that will help them deliver value more effectively. I still firmly believe that sticking to the values and practices of the manifesto will help them in this endeavor.</p>
<p>But once the word agile becomes meaningless, developers can no longer use it as a guide to what is useful in their practice. We may as well simply globally replace the word agile with white space.<sup>2</sup></p>
<section id="move-to-the-right" class="level2">
<h2 data-anchor-id="move-to-the-right">Move to the Right</h2>
<p>Let’s look again at the four values:</p>
<blockquote class="blockquote">
<p><strong>Individuals and Interactions</strong> over Processes and Tools<br>
<strong>Working Software</strong> over Comprehensive Documentation<br>
<strong>Customer Collaboration</strong> over Contract Negotiation, and<br>
<strong>Responding to Change</strong> over Following a Plan</p>
</blockquote>
<p>The phrases on the left represent an ideal—given the choice between left and right, those who develop software with agility will favor the left.</p>
<p>Now look at the consultants and vendors who say they’ll get you started with “Agile.” Ask yourself where they are positioned on the left-right axis. My guess is that you’ll find them process and tool heavy, with many suggested work products (consultant-speak for documents to keep managers happy) and considerably more planning than the contents of a whiteboard and some sticky notes.</p>
<p>If you see this too, then it’s more evidence of the corruption and devaluation of the word “agile.”</p>
<p>(Of course, some of these consultants may well have paid for a two-day training course. I haven’t, so they are masters and I am not, which means I’m probably wrong.)</p>
</section>
<section id="back-to-the-basics" class="level2">
<h2 data-anchor-id="back-to-the-basics">Back to the Basics</h2>
<p>Here is how to do something in an agile fashion:</p>
<p>What to do:</p>
<ul>
<li>Find out where you are</li>
<li>Take a small step towards your goal</li>
<li>Adjust your understanding based on what you learned</li>
<li>Repeat</li>
</ul>
<p>How to do it:</p>
<blockquote class="blockquote">
<p>When faced with two or more alternatives that deliver roughly the same value, take the path that makes future change easier.</p>
</blockquote>
<p>And that’s it. Those four lines and one practice encompass everything there is to know about effective software development. Of course, this involves a fair amount of thinking, and the basic loop is nested fractally inside itself many times as you focus on everything from variable naming to long-term delivery, but anyone who comes up with something bigger or more complex is just trying to sell you something.</p>
<p>All of these sentences are imperative—they are based on verbs telling us what to do and how to do it.</p>
<p>And that leads me to my suggestion.</p>
<p>Let’s abandon the word agile to the people who don’t do things.</p>
<p>Instead, let’s use a word that describes what we do.</p>
<section id="lets-develop-with-agility" class="level3">
<h3 data-anchor-id="lets-develop-with-agility">Let’s develop with <em>agility</em></h3>
<ul>
<li><p>You aren’t an agile programmer—you’re a programmer who programs with agility.</p></li>
<li><p>You don’t work on an agile team—your team exhibits agility.</p></li>
<li><p>You don’t use agile tools—you use tools that enhance your agility.</p></li>
</ul>
<p>It’s easy to tack the word “agile” onto just about anything. Agility is harder to misappropriate.</p>
<p>And that’s important—you can buy and sell labels. Attend a short course, and suddenly you can add a label to your job title. But you can’t buy experience—you can only earn it.</p>
</section>
<section id="and-lets-protect-our-investment" class="level3">
<h3 data-anchor-id="and-lets-protect-our-investment">And let’s protect our investment</h3>
<p>Ultimately, what we do trumps what we call it. But good words help us communicate effectively.</p>
<p>We’ve lost the word agile. Let’s try to hang on to agility. Let’s keep it meaningful, and let’s protect it from those who would take the soul of our ideas in order to sell it back to us.</p>
<blockquote class="blockquote">
<p>info Updated 3/11 Thanks to numerous folks who pointed out I’d mislabeled “agility” as an adverb. Also fixed the hyperlink to the Manifesto for Agile Software Development.</p>
</blockquote>
<p>{% attribution Photo by <a href="https://unsplash.com/@sandym10?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Sandy Millar</a> on <a href="https://unsplash.com/s/photos/death?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a> %}</p>


</section>
</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>I started thinking about this blog post while I was visiting Agile India 2014, my one and only conference on agility. I went to that not because of the topic, but because of my respect for the organizer, <a href="http://nareshjain.com/">Naresh Jain</a>.↩︎</p></li>
<li id="fn2"><p>And, yes, I’ve fallen into the trap myself. When Ruby on Rails came along, I was impressed with the agility it gave me when working on web projects, so I called the book I wrote “Agile Web Development with Rails.” If I was writing that book today, the title would be different.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>agility</category>
  <category>process</category>
  <guid>https://pragdave.me/thoughts/active/2014-03-04-time-to-kill-agile.html</guid>
  <pubDate>Tue, 04 Mar 2014 06:00:00 GMT</pubDate>
  <media:content url="https://pragdave.me/thoughts/assets/sandy-millar-cQ-66Evaf5g-unsplash.jpg" medium="image" type="image/jpeg"/>
</item>
</channel>
</rss>
