<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mike Brinker</title><description>I’m a software engineer interested in how programs, systems, and agents organize knowledge to augment the experience of being human.</description><link>https://mikebrinker.net</link><language>en-us</language><atom:link href="https://mikebrinker.net/rss.xml" rel="self" type="application/rss+xml"/><item><title>Spec-Driven Development: Skeleton Coding</title><link>https://mikebrinker.net/reading/skeleton-coding</link><guid isPermaLink="true">https://mikebrinker.net/reading/skeleton-coding</guid><description>This paper shows that the level of correctness in programs generated by agents improves when an engineer specifies the structure of the desired program in addition to its behavior. Written by folks connected to AWS.</description><pubDate>Wed, 11 Nov 2026 18:59:15 GMT</pubDate><content:encoded>&lt;p&gt;Source: &lt;cite&gt;&lt;a href=&quot;https://arxiv.org/html/2610.38214v1&quot;&gt;Skeleton Coding&lt;/a&gt;&lt;/cite&gt; — Aditya Golatkar et al. · arXiv&lt;/p&gt;&lt;p&gt;At the philosophical level, I would say this paper explores the inextricable symbiosis between form and function. The way software’s behavior is verified depends on the structure of the software. Cynically, one may conclude “oh look, when humans write the code, the quality is better!”. I myself have desired a better abstraction of defining and discussing code with agents. Ultimately, this paper may just be showing or rediscovering the truth encoded in this comic:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mikebrinker.net/_emdash/api/media/file/01M75ZD4VJRG6F2M6CJMYEBS21.01M75ZD5984DBNBF44ECCAJW64.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In my experience, I spend the most time correcting the output of agents when it comes to the structure of the program. For whatever reason, they seldom build the structure the way that I would. The structures they generate often do not follow trajectory I have in my head for the ideal overall structure of the system but rather adhere to “local” examples in the current codebase which are desirable generally or in this particular case. Or they misuse an existing pattern. Or they employ unnecessary artifices.&lt;/p&gt;
&lt;p&gt;This paper implicitly identifies an ability gap in current models which could be improved in the future. Models today can create programs that behave as expected (generally so, to some degree) but do not create programs with structure that skilled people would consider to be “good”. This matches my experience interacting with agents every day.&lt;/p&gt;
&lt;p&gt;The paper concludes that structure specifications improve correctness more than behavioral specifications alone. Improvement in correctness is higher when the structural specifications are written in a code-like format compared to prose.&lt;/p&gt;
&lt;h2&gt;Favorite Quotes&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Ideally, this separation of concerns between the what and the how promises to free developers from
the laborious task of writing code. However, we show that it can actually exponentially increase
the effort required.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Developers rarely begin with a complete specifications; they adapt it to correct issues and steer the
agent toward the goal. However, since prompting a model does not perform Bayesian conditioning [8], there is no guarantee that providing additional specifications will eventually converge to the
goal. However, adding formally verifiable contracts [9, 10, 11] to the skeletons circumvent the issue
(Theorem 3.1). Even when informal contracts are not used, an imperfect verifier can still ensure
faster convergence to a valid implementation (Theorem 3.2).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Structural specifications produce less eroded code than behavioral specifications: Across all benchmarks and models, structural specifications reduce code erosion by up to 24.7%, compared to the task-only prompt. Meanwhile, behavioral specifications increase it. Verbosity varies little across conditions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Originally encountered &lt;a href=&quot;https://x.com/rockatanescu/status/2119348595321155584&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;on X&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Components of Agent Memory</title><link>https://mikebrinker.net/reading/components-of-agent-memory</link><guid isPermaLink="true">https://mikebrinker.net/reading/components-of-agent-memory</guid><description>Written by Anthropic staff, this article covers the information architecture of Claude&apos;s memory system as well as various attempts to measure and improve it.</description><pubDate>Tue, 10 Nov 2026 17:00:58 GMT</pubDate><content:encoded>&lt;p&gt;Source: &lt;cite&gt;&lt;a href=&quot;https://www.anthropic.com/research/components-of-agent-memory&quot;&gt;The components of agent memory&lt;/a&gt;&lt;/cite&gt; — Lance Martin · Anthropic&lt;/p&gt;&lt;p&gt;This article explores the design of memory systems for agents. A pertinent question alluded to is: &lt;em&gt;how can an actor decide what to remember now when it doesn’t know what’s next?&lt;/em&gt; The ideas contain much anthropoligizing of Claude (comparing memory systems to the human brain). While I think there are problems with constantly seeking to understand agents through an anthropological lens, many of the connections are admittedly interesting. I can sympathize with the stated tradeoff where taking good notes while working on something can be distracting, but perfecting the notes later is resource-intensive. I appreciated the writing style that includes references to the humanities. A bit of Kierkegaard and Borges enriches almost any experience!&lt;/p&gt;
&lt;p&gt;The memory system described contains a hierarchy (from top to bottom):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Injected context (smallest)&lt;/li&gt;
&lt;li&gt;Memory representations (e.g. wikis)&lt;/li&gt;
&lt;li&gt;Memory Notes&lt;/li&gt;
&lt;li&gt;Transcripts (event logs)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“Dreaming” is then a process that moves information up the hierarchy while verifying against the layers below.&lt;/p&gt;
&lt;h2&gt;Observations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Opus 5.5 and Sonnet 5.5 had very similar scores on CL-Bench.&lt;/li&gt;
&lt;li&gt;There is explicit mention of Claude being evaluated on its ability to play &lt;em&gt;Pokemon Red&lt;/em&gt;. This connects to rumors that the advances gained in current frontier models largely come from reinforcement learning via playing games.&lt;/li&gt;
&lt;li&gt;The better the model, the more selective it was in recording memories.&lt;/li&gt;
&lt;li&gt;Giving explicit instructions for how to use memory helped older models much more than newer ones.&lt;/li&gt;
&lt;li&gt;Providing a search tool in addition to raw file access to the memory wiki reduced token usage and improved eval scores.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sources referenced:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://continual-learning-bench.com/news/cl-bench-1-0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Continual Learning Bench (CL-Bench) 1.0&lt;/a&gt; (eval)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;LLM Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://platform.claude.com/cookbook/managed-agents-cma-dreaming-with-a-dynamic-workflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Dreaming with a dynamic workflow&lt;/a&gt; (cookbook)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/anthropics/claude-quickstarts/tree/main/managed-agents/knowledge-wiki&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Knowledge wiki with a dynamic workflow&lt;/a&gt; (quickstart)&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>The October 2026 Inflection</title><link>https://mikebrinker.net/blog/october-2026-inflection</link><guid isPermaLink="true">https://mikebrinker.net/blog/october-2026-inflection</guid><description>October 2026 represents a new inflection point in the attitudes toward agentic development we see among leading personalities in the field.</description><pubDate>Fri, 23 Oct 2026 14:12:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://mikebrinker.net/_emdash/api/media/file/5K40Q7QKE9AN1DGTSCC9BHKBF0.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;&lt;p&gt;In 2025, there was a widely regarded inflection point in the software engineering professional community. Opus 4.5 was released on November 24. I remember being thrilled that when I asked it to implement something on my personal projects, the result was something that generally worked. Up to this point, it would take multiple iterations of prompting to get a working result (if one wasn’t writing any code themselves). Then, from December 25 - 31 in 2025, Anthropic gave Pro and Max users double the usage. I remember coming back to work in January feeling different about the role that AI would have in my daily work as a software engineer. Much of the commentary I saw online matched this sentiment. Over time &lt;a href=&quot;https://simonwillison.net/2026/Jan/4/inflection/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Simon Willison&lt;/a&gt;, &lt;a href=&quot;https://martinfowler.com/bliki/NovemberInflection.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Martin Fowler&lt;/a&gt;, and &lt;a href=&quot;https://x.com/karpathy/status/2026731645169185220&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Andrej Karpathy&lt;/a&gt; (among others) acknowledged the impact of this inflection point.&lt;/p&gt;
&lt;p&gt;In October 2026, I believe we’re at another inflection point. If the aforementioned one convinced people that agents were capable of producing the work, this new point that we find ourselves at has more people than ever convinced that agents can or will have the ability to replace human software engineers. I’ve been conflicted and skeptical about this at least since GitHub Copilot &lt;a href=&quot;https://github.blog/news-insights/product-news/github-copilot-is-generally-available-to-all-developers/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;was launched in 2022&lt;/a&gt;. While I don’t think that we can be sure about the future holds for profession and our employment in it, it sure seems like we’ve crossed a line with no chance of turning back.&lt;/p&gt;
&lt;p&gt;I have been experimenting with large language models since 2022. For what felt like a long period of time, the people who had influenced my most in my career were silent or distant about the prospect of using AI to write code. Then, in the last 12 months, all of them have seemingly been converted to this new way of working.&lt;/p&gt;
&lt;p&gt;DHH, the creator of Ruby on Rails, who, in my opinion, spoke most elegantly about the utility of aesthetic beauty of code acknowledged the &lt;a href=&quot;https://www.youtube.com/watch?v=NYFGCESmikA&amp;amp;t=388s&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;November Inflection&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Then we get to November 24th, 2025. Opus 4.5, to me, was the dividing line, where suddenly… I didn’t even try it on the 24th. I think I tried it on the 26th. I gave it a couple of tasks, and I realize that the quality of the output is uncannily close to what I would’ve written. And I remember just leaning back and thinking, “What just happened?”&lt;/p&gt;
&lt;p&gt;How did we go from this autocomplete mess that I was talking to you about in the summer to this just a few short months later? How did we get both the increase in intelligence and then also the increase in usability?” This agent harness question where I don’t know if Opus 4.5 was that much smarter than Opus 4, which is what we had in the summer, but its ability to instrument your computer, to use tools, to check its own work, to apply its intelligence in such a way that you could get real meaningful work out of it, was completely different. And I think this is then the big change that happens for almost anyone who paid attention and started playing with it over the Christmas break.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On September 23, In &lt;a href=&quot;https://www.youtube.com/watch?v=vDjW_dRyKXY&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;a sermonic talk emblematic of the entire point I’m making&lt;/a&gt;, DHH publicly declared his retirement from handwritten code.&lt;/p&gt;
&lt;p&gt;In June 2025, “Uncle” Bob Martin, whose Clean Code left an indelible mark on my coding style , &lt;a href=&quot;https://azuredevops.libsyn.com/uncle-bob-martin-software-leader-episode-357-0?utm_source=chatgpt.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;emphasized caution with AI tools&lt;/a&gt;. He began experimenting public with AI in January 2026. By April &lt;a href=&quot;https://x.com/unclebobmartin/status/2044114698451476492&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;he wasn’t reviewing the code produced by his agents&lt;/a&gt;. He often tweeted about building custom harnesses for his agents to ensure acceptable code quality, but by September &lt;a href=&quot;https://www.aviator.co/podcast/uncle-bob-martin-ai-clean-code&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;he abandoned that too&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Kent Beck, the creator of XP and popularizer of Test-Driven Development was relatively ahead of the curve. In &lt;a href=&quot;https://newsletter.kentbeck.com/p/social-ai-adoption-lessons-from-hybrid&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;April 2025&lt;/a&gt;, he spoke of “coding at 3AM for the first time in decades” due to his use AI.&lt;/p&gt;
&lt;p&gt;Justin Searls, who I fondly remember on &lt;a href=&quot;https://testdouble.com/insights/rethink-tdd-teaching-strategies&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;TDD&lt;/a&gt;, not to mention his &lt;a href=&quot;https://testdouble.com/insights/how-to-program&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;personality test for programmers&lt;/a&gt; &lt;a href=&quot;https://x.com/searls/status/2110545597480718473&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stated&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Over a year ago, I stopped reading code and started automating adversarial agents to perform recursive code reviews instead.&lt;/p&gt;
&lt;p&gt;The result: low-defect systems that do what I want. Can’t believe anyone engaging seriously with these tools still believes human code review is superior&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;DHH, Kent Beck, Uncle Bob, Martin Fowler, and Justin Searls. In terms of people who write books and speak on software engineering, this is who I learned from. 3 of them were architects of the Agile Manifesto. They are all-in on AI now. While I’ve been experimenting with LLMs and code generation since GPT 3.5 and haven’t written basically any code by hand for the last 1.5+ years (!!), I think I now have to admit to myself that it’s time to be all-in.&lt;/p&gt;</content:encoded></item><item><title>Defining a FontFamily for Greek</title><link>https://mikebrinker.net/blog/font-for-greek</link><guid isPermaLink="true">https://mikebrinker.net/blog/font-for-greek</guid><description>I enjoy a beautiful typeface for Greek (or any language for that matter). One of my favorites is the unnamed Greek font used as the default in Logos Bible…</description><pubDate>Thu, 09 Jan 2025 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I enjoy a beautiful typeface for Greek (or any language for that matter). One of my favorites is the unnamed Greek font used as the default in Logos Bible Software. That aside, SIL has a free font which looks great, especially in Greek: &lt;a href=&quot;https://fonts.google.com/specimen/Gentium+Book+Plus&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gentium Book Plus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I decided it would be nice to use this font whenever Greek Unicode characters are present on this site. I wasn’t sure how to accomplish this at first, but it turns out that CSS allows you to specify Unicode ranges when you are defining a font. Along with properly managing the cascade of styles on the site, font definitions like this did the trick:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;@font-face {
  font-family: &quot;SortsMillGoudy&quot;;
  src: url(&quot;../fonts/sorts-mill-goudy/SortsMillGoudy-Regular.ttf&quot;)
    format(&quot;truetype&quot;);
  font-weight: normal;
  font-style: normal;
  unicode-range: U+0000-024F;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;@font-face {
  font-family: &quot;GentiumGreek&quot;;
  src: url(&quot;../fonts/gentium/GentiumBookPlus-Regular.ttf&quot;) format(&quot;truetype&quot;);
  font-weight: 400;
  font-style: normal;
  unicode-range: U+0370-03FF, U+1F00-1FFF; /* Greek ranges */
  font-display: swap;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For English and Code, &lt;code&gt;unicode-range: U+0000-024F&lt;/code&gt; seems to do the trick. And for Greek, I’m using &lt;code&gt;unicode-range: U+0370-03FF, U+1F00-1FFF;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And now, some Greek:&lt;/p&gt;
&lt;p&gt;καὶ τοῦτο προσεύχομαι ἵνα ἡ ἀγάπη ὑμῶν ἔτι μᾶλλον καὶ μᾶλλον περισσεύῃ ἐν ἐπιγνώσει καὶ πάσῃ αἰσθήσει…&lt;/p&gt;</content:encoded></item><item><title>The Dative of Possession</title><link>https://mikebrinker.net/blog/dative-of-possession</link><guid isPermaLink="true">https://mikebrinker.net/blog/dative-of-possession</guid><description>Was your name given to you or created by you?</description><pubDate>Mon, 30 Dec 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Was your name given to you or created by you?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I was confused during a recent Greek lesson in &lt;a href=&quot;https://scripturial.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Scripturial&lt;/a&gt;. Phrases like “my name” and “your name” were being taught as ὄνομα σοι and ὄνομα μοι. To me, σοι and μοι looked like the dative forms when I was expecting the genitive.&lt;/p&gt;
&lt;p&gt;After a quick consultation with ChatGPT (GPT-4o), I was under the impression that for this phrase in particular, Greek speakers would say something like “the name for me” rather than “the name of me” (the latter of which I was expecting based upon my current mental map between Greek and English). In trying to confirm ChatGPT’s answer, I stumbled across this interesting &lt;a href=&quot;https://www.ibiblio.org/bgreek/forum/viewtopic.php?t=2234&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;B-Greek post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The folks discussing this very question on the forum confirmed GPT-4o’s suggestion that the dative is used in Greek to express this idea. They link to a grammar that calls this &lt;a href=&quot;https://www.ibiblio.org/bgreek/project/funk-grammar/pre-alpha/lesson-62.html#s016.4:~:text=The%20dative%20of%20possession&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The Dative of Possession&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The dative of possession&lt;/em&gt; is closely related to the dative of advantage. Simple possession is expressed by the genitive (§888.1); the one for whom something exists (i.e. in his or her interest) is put in the dative…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the forum, the initial answers sounded very similar to what GPT-4o had told me, but later on, some contributors started posting statistics to compare the frequency of constructions like ὅνομά μοι and ὄνομά μου. It ends up looking like both constructions are used somewhat widely and there is variance across time and also whether 1st, 2nd, or 3rd person is being used.&lt;/p&gt;
&lt;p&gt;When I think about it, this construction makes sense. One’s name is given (a name “for” you) rather than generated from them. I suspect that in Greek there is a bit more psychological separation between one’s identity/being and one’s name than there is in English? In English, I &lt;em&gt;am&lt;/em&gt; Mike, &lt;em&gt;my name&lt;/em&gt; is Mike, etc… “Mike” is not a name &lt;em&gt;for&lt;/em&gt; me, it’s my name.&lt;/p&gt;
&lt;p&gt;I continue to find &lt;a href=&quot;https://scripturial.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Scripturial&lt;/a&gt; a very useful way to improve my Greek, while working at a pace that fits with everything else I have going on in life. Like this one though, there are instances where a construction that is taught leaves me with questions that I need to resolve on my own. I suspect that’s a worthwhile tradeoff to make (letting my curiosity dictate further research) in order to keep the curriculum compact.&lt;/p&gt;
&lt;p&gt;This is enough for me to know that I need to recognize ὅνομά μοι and ὄνομά μου as serving a similar purpose without assuming they are identical. I wonder if B-Greek content is part of OpenAI training data? I would guess so. In any case, I’m a bit late to the party, but B-Greek looks like great place to discuss and learn about these sorts of things online.&lt;/p&gt;</content:encoded></item><item><title>Ματαιότης in Romans 8 and Ecclesiastes</title><link>https://mikebrinker.net/blog/mataiotes-romans-8</link><guid isPermaLink="true">https://mikebrinker.net/blog/mataiotes-romans-8</guid><description>Does Romans 8 suggest a Pauline interpretation of Qohelet? I was recently reading through Romans in my morning study time. I noticed that with each successive…</description><pubDate>Tue, 24 Dec 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Does Romans 8 suggest a Pauline interpretation of Qohelet?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I was recently reading through Romans in my morning study time. I noticed that with each successive chapter, I was reading slower and slower. But the time I hit Romans 6, I was getting through less than one chapter a day. At the moment, I’ve been in Romans 8 for several days, and I’ve hit something interesting that I wanted to write down.&lt;/p&gt;
&lt;p&gt;I paused on Romans 8:20 -21:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For the creation has been subjected to futility, not willingly, but because of the one who subjected &lt;em&gt;it&lt;/em&gt;, in hope that the creation itself also will be set free from its servility to decay, into the glorious freedom of the children of God&lt;/p&gt;
&lt;p&gt;W. Hall Harris III et al., eds., &lt;a href=&quot;https://ref.ly/logosres/leb?ref=BibleLEB2.Ro8.20&amp;amp;off=3&amp;amp;ctx=the+sons+of+God.+20%C2%A0~For+the+creation+has&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;The Lexham English Bible&lt;/em&gt;&lt;/a&gt; (Bellingham, WA: Lexham Press, 2012), Ro 8:20–21.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;τῇ γὰρ ματαιότητι ἡ κτίσις ὑπετάγη, οὐχ ἑκοῦσα ἀλλὰ διὰ τὸν ὑποτάξαντα, ἐφʼ ἑλπίδι  21 ὅτι καὶ αὐτὴ ἡ κτίσις ἐλευθερωθήσεται ἀπὸ τῆς δουλείας τῆς φθορᾶς εἰς τὴν ἐλευθερίαν τῆς δόξης τῶν τέκνων τοῦ θεοῦ&lt;/p&gt;
&lt;p&gt;Michael W. Holmes, &lt;a href=&quot;https://ref.ly/logosres/sblgnt?ref=BibleSBLGNT.Ro8.20&amp;amp;off=3&amp;amp;ctx=%CE%BF%E1%BF%A6+%E1%BC%80%CF%80%CE%B5%CE%BA%CE%B4%CE%AD%CF%87%CE%B5%CF%84%CE%B1%CE%B9%C2%B7++20+~%CF%84%E1%BF%87+%CE%B3%E1%BD%B0%CF%81+%CE%BC%CE%B1%CF%84%CE%B1%CE%B9%CF%8C%CF%84%CE%B7%CF%84%CE%B9+%E1%BC%A1+&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;The Greek New Testament: SBL Edition&lt;/em&gt;&lt;/a&gt; (Lexham Press; Society of Biblical Literature, 2011–2013), Ro 8:20–21.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Surely I’ve had more thoughts about this passage over the years than I can remember. This time though, I was trying to ask some basic questions about the idea of creation being subjected: who subjected it? For what purpose was it subjected? I found my answers &lt;em&gt;and&lt;/em&gt; an unexpected (and delightful!) rabbit trail in the commentary of James D.G. Dunn (which I had never read before):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The point Paul is presumably making, through somewhat obscure language, is that God followed the logic of his purposed subjecting of creation to man by subjecting it yet further in consequence of man’s fall, so that it might serve as an appropriate context for fallen man: a futile world to engage the futile mind of man. By describing creation’s subjection as “unwilling” Paul maintains the personification of the previous verse. There is an out-of-sortness, a disjointedness about the created order which makes it a suitable habitation for man at odds with his creator.&lt;/p&gt;
&lt;p&gt;By “futility” Paul probably has in mind the same sense of futility of life which found expression in Jewish thought most clearly in Ecclesiastes—that weariness and despair of spirit which cannot see beyond the stultifying repetitiveness of life, the endless cycle of decay and corruption, the worthlessness of a lifelong effort which may be swept away overnight by a storm or be parched to nothingness in a drought, the complete insignificance of the individual in the tides of time and the currents of human affairs—all indeed that, had man but realized it, was going to make it impossible for him to be “as god,” made it inevitable that he would become subservient to useless idols and mere things. Yet for Paul, of course, that is not, could not be the last word.&lt;/p&gt;
&lt;p&gt;James D. G. Dunn, &lt;em&gt;Romans 1–8&lt;/em&gt;, vol. 38A, Word Biblical Commentary (Dallas: Word, Incorporated, 1988), 487–488.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With my basic questions of comprehension satisfied in the first paragraph, I turned with interest to this idea of “futility”. I had never considered a connection to Ecclesiastes here before, despite my long-term interest in it. As I thought about it, I became excited because I began to wonder if we have a latent New Testament interpretation of Ecclesiastes here. There has been much argument and little consensus in the Christian tradition about the use or application of Ecclesiastes. Is it an accurate view of how things are, with a conclusion that is so orthodox it’s nearly boring ()? Or is it a cautionary tale of what life is like in the world without God (i.e. “under the Sun”)?&lt;/p&gt;
&lt;p&gt;Well, before getting to far ahead of myself, I was desiring a concrete linkage between this passage and Ecclesiastes that was perhaps more solid than interpretation of Dunn and my penchant to see an allusion.&lt;/p&gt;
&lt;p&gt;ματαιότης is the word for “futility” in verse 20. I hadn’t seen this one before, so I took a quick look at the word family in NIDNTTE:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;μάταιος &lt;a href=&quot;https://ref.ly/logosref/dbl$2Bg.3469&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;G3469&lt;/a&gt; (mataios), vain, empty, worthless, futile, deceptive; ματαιότης &lt;a href=&quot;https://ref.ly/logosref/dbl$2Bg.3470&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;G3470&lt;/a&gt; (mataiotēs), emptiness, futility, worthlessness; ματαιόω &lt;a href=&quot;https://ref.ly/logosref/dbl$2Bg.3471&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;G3471&lt;/a&gt; (mataioō), to render futile or worthless; μάτην &lt;a href=&quot;https://ref.ly/logosref/dbl$2Bg.3472&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;G3472&lt;/a&gt; (matēn), in vain, to no end; ματαιολογία &lt;a href=&quot;https://ref.ly/logosref/dbl$2Bg.3467&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;G3467&lt;/a&gt; (mataiologia), useless talk, empty prattle; ματαιολόγος &lt;a href=&quot;https://ref.ly/logosref/dbl$2Bg.3468&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;G3468&lt;/a&gt; (mataiologos), babbling, subst. idle talker&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pretty consistent! Now, in the past, I had become convinced of a translation like “vapor” being best for &lt;em&gt;hebel&lt;/em&gt; in the Hebrew text of Ecclesiastes, but something made me wonder how the LXX translated it. So I took a look at the LXX and what did I find?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ματαιότης ματαιοτήτων, εἶπεν ὁ ἐκκλησιαστής, 
ματαιότης ματαιοτήτων, τὰ πάντα ματαιότης.&lt;/p&gt;
&lt;p&gt;Henry Barclay Swete, &lt;a href=&quot;https://ref.ly/logosres/otgrkswetetxt?ref=BibleLXX2.Ec1.2&amp;amp;off=2&amp;amp;ctx=%CE%BB+%E1%BC%90%CE%BD+%E1%BC%B8%CE%B5%CF%81%CE%BF%CF%85%CF%83%CE%B1%CE%BB%CE%AE%CE%BC.+%0a2+~%CE%9C%CE%B1%CF%84%CE%B1%CE%B9%CF%8C%CF%84%CE%B7%CF%82+%CE%BC%CE%B1%CF%84%CE%B1%CE%B9%CE%BF%CF%84%CE%AE%CF%84%CF%89&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;The Old Testament in Greek: According to the Septuagint&lt;/em&gt;&lt;/a&gt; (Cambridge, UK: Cambridge University Press, 1909), Ec 1:2.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The opening speech of Ecclesiastes (not to mention the rest of it) is &lt;em&gt;chock full&lt;/em&gt; of ματαιότης! So I felt better about a connection between the outlook of Ecclesiastes and Paul’s use of ματαιότης in Romans 8. So what does it all mean?&lt;/p&gt;
&lt;p&gt;The big thing that came to mind was that in these comments in Romans 8, Paul is talking about an “emplotted” state of affairs, that is the act of creation being subject to futility is not how things originally were or will finally be, but instead it is how they are now at this point in the “story”.&lt;/p&gt;
&lt;p&gt;This has potentially big implications for me in my understanding of Ecclesiastes – the very &lt;em&gt;real&lt;/em&gt; and resonant way the Qohelet speaks about world is both factual (truthful about how things are) and yet not-as-they-should-be. So, potentially, from Paul’s allusion to it here, we can see that he understood Ecclesiastes to be accurately depicting the world and our experience of it while proclaiming that things will not always be this way. I had never noticed this before, but it fits well with what I understand Paul to be saying up to this point in Romans.&lt;/p&gt;
&lt;p&gt;Conclusions? Well, I’m interested to find out what might be in the tradition about the connection here. This has also made me a bit curious about what the concrete criteria might be to declare an allusion. I would guess that use of a word isn’t enough on its own, but in this case there is the lexical link and a thematic “kinship”.&lt;/p&gt;</content:encoded></item><item><title>βίβλος and βιβλίον</title><link>https://mikebrinker.net/blog/biblos-biblion</link><guid isPermaLink="true">https://mikebrinker.net/blog/biblos-biblion</guid><description>Earlier this year I started incorporating Scripturial into my Greek learning. Early on, Scripturial introduced βιβλίον as “book”. So for the last few months…</description><pubDate>Mon, 23 Dec 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Earlier this year I started incorporating &lt;a href=&quot;https://scripturial.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Scripturial&lt;/a&gt; into my Greek learning. Early on, Scripturial introduced βιβλίον as “book”. So for the last few months, thinking about “book” I reached for βιβλίον. I recently encountered Βίβλος and was a bit confused. I thought βιβλίον was a neuter noun referring to “book”. Βίβλος appeared to be a masculine noun that also referred to book or scroll.&lt;/p&gt;
&lt;p&gt;The Lexham Theological Wordbook confirmed what I thought I knew about βιβλίον:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;βιβλίον (biblion) n. neut. scroll, document. A written document. This is most common term for a scroll in the NT.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The entry for βίβλος surprised me though:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;βίβλος (biblos). n. fem. book. Refers to any written composition, including sacred books.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;βίβλος is a &lt;em&gt;feminine&lt;/em&gt; noun that refers to any written composition?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As I often do with questions that I guess have rudimentary answers, I quickly asked ChatGPT (to the extent I can verify its answers; they seem fairly trustworthy with lexical questions in Ancient Greek). ChatGPT told me that βιβλίον is “diminutive” (originally referred to a little Βίβλος) and eventually became the most common usage. &lt;strong&gt;NIDNTTE&lt;/strong&gt; confirmed and expanded this suggestion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Presumably, the word came to mean “papyrus” because this writing material was exported to Greece through Byblos, where the plant was prepared. The diminutive form βυβλίον/βιβλίον referred to a strip of βίβλος, thus a piece of writing material, and then by extension it came to mean “document, letter” (Hdt. 3.128.2–3); eventually it too could refer to a scroll or book and thus could be used synonymously with βίβλος (a “doubly diminutive” form βιβλίδιον is attested as early as Demosth.). From the pl. τὰ βιβλία, “the books,” derives Lat. &lt;em&gt;biblia&lt;/em&gt; and thence Eng. &lt;em&gt;Bible&lt;/em&gt;… In the LXX the term βίβλος occurs almost 30× (βύβλος only in 2 Chr 17:9; Dan 9:2 [Th.]; 1 Esd 1:31), but βιβλίον c. 185×.&lt;/p&gt;
&lt;p&gt;Moisés Silva, ed., &lt;a href=&quot;https://ref.ly/logosres/nidnttrev?ref=DBLGreek.DBLG+1044&amp;amp;off=662&amp;amp;ctx=ce+in+Transjordan&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;New International Dictionary of New Testament Theology and Exegesis&lt;/em&gt;&lt;/a&gt;. (Grand Rapids, MI: Zondervan, 2014), 511.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Already by the time of the Septuagint, it looks like βιβλίον was far more common. Even in the New Testament, I found 10 instances of βίβλος and 34 for βιβλίον.&lt;/p&gt;
&lt;p&gt;Even after multiple years of personal study in Ancient Greek, the mere gender of a word can get the best of me! There’s much to be curious about here. What came first, the origin of papyrus (The port city &lt;em&gt;Byblos&lt;/em&gt;) or the word for papyrus? What characteristic of language do we see in the way the diminutive form became most common? Learning never ends and the language is more than my understanding of it.&lt;/p&gt;</content:encoded></item><item><title>Working with AI, State of the Union June 2024</title><link>https://mikebrinker.net/blog/working-with-ai-state-of-the-union</link><guid isPermaLink="true">https://mikebrinker.net/blog/working-with-ai-state-of-the-union</guid><description>Exploring a new concept with Claude Sonnet 3.5</description><pubDate>Fri, 21 Jun 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This post explores what it is like to work with AI in a software development context.
With our current rate of growth, this experience changes significantly every 3 - 6 months.
In this installment, I chronicle an experiment of exploring a new concept by building a PoC
using Claude Sonnet 3.5 and Anthropic’s new Artifacts feature.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This week, &lt;span class=&quot;small-caps&quot;&gt;Anthropic&lt;/span&gt; released &lt;span class=&quot;small-caps&quot;&gt;Claude Sonnet 3.5&lt;/span&gt; along with a new feature they call &lt;span class=&quot;small-caps&quot;&gt;Artifacts&lt;/span&gt;.
&lt;a href=&quot;https://www.anthropic.com/news/claude-3-5-sonnet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;According to Anthropic’s numbers&lt;/a&gt;, this new model outperforms even the recently released (and poorly named) &lt;abbr class=&quot;acronym&quot;&gt;GPT&lt;/abbr&gt;-4o.
Buried in that same article, you will find a description of Anthropic’s new &lt;span class=&quot;small-caps&quot;&gt;Artifacts&lt;/span&gt; feature.
As far as I can tell, &lt;span class=&quot;small-caps&quot;&gt;Artifacts&lt;/span&gt; allow you to focus on making and improving a particular thing (program, image, etc.) throughout the larger context of a conversation with the model.
Many artifacts can exist per conversation. Programmatic ones allow you to see code with a running preview and are versioned!&lt;/p&gt;
&lt;p&gt;Below, I’ll briefly describe my experience with this new release.
For additional context, you may want to &lt;a href=&quot;https://audio-alignment-poc.netlify.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;try the result yourself&lt;/a&gt;.
As a test case, I wanted to explore the process of creating alignment data for an audio Bible.
Why? Much of my day job revolves around developing an &lt;a href=&quot;https://biblica.gitbook.io/clear-aligner&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;alignment tool&lt;/a&gt; for text-based Bibles.
If you’re not familiar, “alignment data” describes the relationships between texts at the level of words, groups of words, or parts of words.
At &lt;span class=&quot;small-caps&quot;&gt;Biblica&lt;/span&gt;, we’re focused on aligning translations to Hebrew and Greek sources so that we can project source annotations through translations that are written in modern languages.
Anyway, I wanted to explore a user experience focused on aligning an audio bible.&lt;/p&gt;
&lt;p&gt;So what was it like collaborating with &lt;abbr class=&quot;acronym&quot;&gt;AI&lt;/abbr&gt; in June 2024?&lt;/p&gt;
&lt;p&gt;The new &lt;span class=&quot;small-caps&quot;&gt;Artifacts&lt;/span&gt; feature is a big step in the right direction.
It just &lt;em&gt;removes&lt;/em&gt; all kinds of annoyances that have come from coding with &lt;abbr class=&quot;acronym&quot;&gt;GPT&lt;/abbr&gt;-4 in the past.
It keeps the thing you are working on front and center, the artifact in context properly,
and allows you to easily switch between versions without scrolling through a long conversation.&lt;/p&gt;
&lt;p&gt;The coding abilities of &lt;span class=&quot;small-caps&quot;&gt;Claude Sonnet 3.5&lt;/span&gt; are also excellent.
It used a variety of libraries during our prototyping when appropriate.
It also had good first-draft styling and design ideas.
The most impressive part was that, for a fairly complex domain (aligning an audio bible, dealing with multiple languages, etc.), it rarely took more than a sentence or two to describe my intent.
This last part is worth emphasizing: &lt;em&gt;this model understood my ideas as I produced them. Never once did it seem to misunderstand what I wanted to accomplish&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;There is still a lot of work to be done, though.&lt;/p&gt;
&lt;p&gt;Most of the logic we built for this little concept demo was written in a single React component.
In my local code repository, I had a few other boiler files for loading and displaying the component. Claude was aware of those but was mostly just writing code for my main react component.
If I wanted to do some refactoring and split this component up, there did not seem to be a good or easy way to accomplish that with what is available today.
Working in a single component isn’t the end of the world though, especially if Claude is writign all the code for me.
Unfortunately, though, things got sketchy when the component grew to ~200 LOC. The model’s code output began to have rudimentary syntax errors like missing opening braces for an if statement.
Beyond that, it didn’t want to reproduce the entire component during each iteration, so it would print fragments of the component that I would have to carefully replace in my local code repository.
Beyond the syntax errors, the fragments were often functional, but where to put them wasn’t always obvious.&lt;/p&gt;
&lt;p&gt;Overall, the prototyping experience was speedy and productive in the beginning – magically so.
But when we hit that threshold, a lot of the magic disappeared.&lt;/p&gt;
&lt;p&gt;I had some more UI/UX ideas, but I decided to stop when the syntax errors stopped. Then, it was time to deploy to Netflify so I could share the working PoC. At this point, I ran into issues with hosting the mp3 file for the demo in Netlify.
The prototype used audio ranges, which the Netlify HTTP server did not seem to support. I was asking Claude for advice on this when I hit my Claude request limit.
I’m a paying customer for Claude Pro, mind you, and I still hit the limit before I was able to take this small PoC across the finish line.&lt;/p&gt;
&lt;p&gt;I ended up finishing the deployment without Claude’s help. One of the features that we had programmed for the PoC was left broken (the audio snippet for particular tokens should play when you click on them).&lt;/p&gt;
&lt;p&gt;All in all, the early prototyping experience was honestly magicial. Claude was bringing my ideas to life, typing all the code for me.
But even with my subscription, Claude couldn’t take me from idea to deployment. This was for a PoC, the core logic of which was ~250 LOC. I don’t think I could depend on Claude for larger projects, not even for a whole half-day work session.&lt;/p&gt;
&lt;p&gt;When it comes to Generative AI, there is so much to be excited about. We also have a &lt;em&gt;long&lt;/em&gt; way to go. I’m looking forward to what comes next.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://audio-alignment-poc.netlify.app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Try the result on Netlify&lt;/a&gt;&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;&lt;a href=&quot;https://github.com/themikejr/audio-bible-alignment-poc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Look at the code on Github&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;</content:encoded></item><item><title>A Canticle for Leibowitz</title><link>https://mikebrinker.net/blog/A-Canticle-For-Leibowitz</link><guid isPermaLink="true">https://mikebrinker.net/blog/A-Canticle-For-Leibowitz</guid><description>Walter M. Miller Jr. · 1959 · 334 pages I first heard about this book from my custom GPT, Reading Companion (a mentor for book discovery). Try it yourself and…</description><pubDate>Sun, 07 Jan 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Walter M. Miller Jr. · 1959 · 334 pages&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I first heard about this book from my custom GPT, &lt;a href=&quot;https://chat.openai.com/g/g-zssGR0rPL-reading-companion&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span class=&quot;small-caps&quot;&gt;Reading Companion&lt;/span&gt;&lt;/a&gt; (a mentor for book discovery). Try it yourself and you might discover an amazing book!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mikebrinker.net/assets/images/a-canticle-for-leibowitz.png&quot; alt=&quot;A Canticle for Leibowitz&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This fine specimen obtained at my local Barnes &amp;amp; Noble.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;small-caps&quot;&gt;A Canticle for Leibowitz&lt;/span&gt; was a Hugo Award winner in 1961. The book is set on post-apocalyptic earth. Over a series of centuries, the plot follows a series of monks whose use scribal practices to preserve the last known written remnants from the previous age. The book has an incredibly good combination of positive features — unique humor, characters that engender empathy, meditations on perennial wisdom topics, and geeky linguistic quirks to boot.&lt;/p&gt;
&lt;p&gt;One character that I could feel for is a monk named Brother Francis. We are introduced to him as he is fasting in the desert as part of a process from being promoted from novice to take lifelong vows. It’s made clear that he feels suicide to be his only other viable option if he can’t make it into the order. He’s not a good fighter and doesn’t have the stomach to live out life in what seems like a very Mad Max type of situation. The life of a monk in the Albertian Order of Leibowitz can be austerely severe in its own ways though. A successful life is spent developing myopia as one copies often unintelligible texts by candlelight.&lt;/p&gt;
&lt;p&gt;There are several scenes where the order of monks exhibit a combination of ignorance and reverence for the texts that I can only describe as charming. I won’t ruin all the fun, but imagine a dark age monk preserving circuit diagrams with no understanding of electricity and being so enamoured with the symmetry and intricacy of the design that he cannot help but illuminate his copy of the diagram with swords, crosses, flowers, and the like.&lt;/p&gt;
&lt;p&gt;Perhaps the centerpiece of the book is when scientific inclination begins to return to humanity. There is now a leading scholar who is pushing to achieve the understanding and command of the world that was lost after the “deluge” (though his pride is doomed to merely rediscover what came before). This leading scholar makes a journey to the abbey where the monks preserve texts. With a skeptical eye akin to 19th century German Biblical Criticism, the scholar studies the faithfully preserved texts with plenty of theories about how their transmission could have gone wrong. Several conversations the monks have with the scholar give shape to a dynamic where I’ve felt tension myself. That is, on the hand, the religious inclination to preserve ancient knowledge (perhaps not fully understood) and on the other, the scientific proclivity for certainty that we see even today. The way that Miller uses the future setting to shed light on discussions like these that we have in our own time is even-handed, artful, and thought-provoking.&lt;/p&gt;
&lt;p&gt;As time goes on, humanity gets ever closer to achieving the power and command they once had. This phase of the novel gives the author opportunities to explore theodicy in a way that feels honest and fresh to this reader. I could go on — there is a memorable visit with the Pope of New Rome that takes place, a prophetic Hebrew character that is interwoven in the plot and many more interesting and enjoyable moments. If you have any interest in Science Fiction, Christianity, scribal practices, linguistics, and the like, I think &lt;span class=&quot;small-caps&quot;&gt;A Canticle for Leibowitz&lt;/span&gt; is likely to be worth your time.&lt;/p&gt;</content:encoded></item><item><title>Rebooting My Writing Practice</title><link>https://mikebrinker.net/blog/reboot-my-writing-practice</link><guid isPermaLink="true">https://mikebrinker.net/blog/reboot-my-writing-practice</guid><description>This year, one intention I have is to reboot my public writing practice. In 2023, I learned the same lesson over and over again: writing improves my ability to…</description><pubDate>Mon, 01 Jan 2024 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This year, one intention I have is to reboot my public writing practice.&lt;/p&gt;
&lt;p&gt;In 2023, I learned the same lesson over and over again: &lt;em&gt;writing improves my ability to think&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Early in 2023, I had the privilege of attending the &lt;a href=&quot;https://www.linkingyourthinking.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Linking Your Thinking&lt;/a&gt; workshop. I went into the experience hoping to learn &lt;span class=&quot;small-caps&quot;&gt;the one true way to organize my second brain&lt;/span&gt;. While that initial hope was severely deflated, I did learn the value of &lt;em&gt;production&lt;/em&gt; as it pertains to thinking. Through a series of exercises at the workshop, I saw that the act of encoding ideas/thinking in writing leads to new ideas and new connections between them. If I spend even 30 minutes a day on some sort of writing practice, I find myself spontaneously having more ideas – generally, life gets more interesting. I used to think of my notes as some sacred cache of knowledge I was creating (that no one actually cared about), but now I see my notes as a vehicle for thought.&lt;/p&gt;
&lt;p&gt;Additionally, through continuing with my &lt;a href=&quot;https://bulletjournal.com/blogs/faq/what-is-the-bullet-journal-method&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Bullet Journaling&lt;/a&gt; practice, I saw that logging my activities, thoughts, questions, and gratitude helped me gain a better perspective on my circumstances and responses. Processing thoughts with logging didn’t make all my problems go away, but it did help me be a bit more present amidst the constant churn of distractions that surround me in daily life.&lt;/p&gt;
&lt;p&gt;Finally, as I’ve embraced &lt;abbr class=&quot;acronym&quot;&gt;AI&lt;/abbr&gt; (read: LLMs with a chat interface), I’ve seen that often the largest barrier to getting them to help me in the way that I want is encoding sufficient context regarding my task at hand. I think that for knowledge workers to benefit from generative AI tools, it’s going to mean more writing, not less. I expect that figuring out the right context to encode in writing will be a determining factor for how helpful &lt;abbr class=&quot;acronym&quot;&gt;AI&lt;/abbr&gt; will be for the average knowledge worker as it inevitably continues its explosion onto the market.&lt;/p&gt;
&lt;p&gt;I don’t have grand plans for this iteration of my website, but I do intend for it be be an outlet for writing and &lt;a href=&quot;https://www.swyx.io/learn-in-public&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;learning in public&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here’s to &lt;span class=&quot;small-caps&quot;&gt;2024&lt;/span&gt;!&lt;/p&gt;</content:encoded></item><item><title>On 10 Years of Making Software</title><link>https://mikebrinker.net/blog/10-years-of-software</link><guid isPermaLink="true">https://mikebrinker.net/blog/10-years-of-software</guid><description>A Retrospective</description><pubDate>Wed, 30 Nov 2022 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This year I realized I am now 10 years into a career in making software. As I reflected on my experience thus far I began to see certain themes that continue to resonate with me in my work. The writing below is an attempt to explore those themes in the hope of better understanding my motivations and what I should seek in the next phase of the journey.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As the point in time that I began &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; moves farther and farther away, I oscillate between feeling as if it began a long time ago and as if it was yesterday. Surely though, much has changed in that time — not only about me but about the world we all live and work in. When I started in 2012, open offices were just washing ashore at the conservatively-cultured bank that I worked at. I was put on an &lt;span class=&quot;small-caps&quot;&gt;agile&lt;/span&gt; scrum team of five developers along with a &lt;abbr class=&quot;acronym&quot;&gt;QA&lt;/abbr&gt; and a &lt;span class=&quot;small-caps&quot;&gt;Scrum Master&lt;/span&gt;. We were &lt;em&gt;literally&lt;/em&gt; making a spreadsheet for the web. While learning to sling code in Java 6 I was fed a robust diet of methodological guidance both in theory and in practice. &lt;abbr class=&quot;acronym&quot;&gt;TDD&lt;/abbr&gt;, &lt;span class=&quot;small-caps&quot;&gt;Story Points&lt;/span&gt;, &lt;span class=&quot;small-caps&quot;&gt;Sprints&lt;/span&gt;, &lt;span class=&quot;small-caps&quot;&gt;Clean Code&lt;/span&gt;. There were just as many new buzzwords as experiences in those early months. I watched mustachioed, grown men passionately yell at groups of other humans about &lt;abbr class=&quot;acronym&quot;&gt;ESB&lt;/abbr&gt;s (Enterprise Service Bus… don’t look it up). We strove to automate our deployments, bring agility to company culture, and iteratively deliver value to customers. The best days were a surreal mixture of science fiction, fantasy, and late 90s office decor. Sometimes when the developers would get together to solve a problem, I felt like an X-Wing pilot listening to General Dodonna’s briefing as I was about to assault the Death Star.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mikebrinker.net/assets/images/dodonna-briefing.png&quot; alt=&quot;General Dodonna&apos;s Briefing&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On the worst days, I often felt as though I had tasted the future (surely an &lt;span class=&quot;small-caps&quot;&gt;AGILE&lt;/span&gt; mindset could solve the problems besetting &lt;abbr class=&quot;acronym&quot;&gt;IT&lt;/abbr&gt; projects and society at large) but was held back by the red tape and stodgy outlooks of middle-management at the medium-sized regional bank where I held my employ.&lt;/p&gt;
&lt;p&gt;Much has changed since those days for me and others — some of which might even be worth discussing. My goal here is to reflect on what it is about making software that I continue to find so enriching. Most of this is inextricably tied up in my journey: the extremely helpful mentor I had early on, the insane situations I happened upon, the friends I made, the mistakes I committed, and the internal commitments, failures, fears, and strivings of my own fickle heart. Perhaps though, the themes here are deep enough that they are helpful to others for reflection as well.&lt;/p&gt;
&lt;h2&gt;Identity&lt;/h2&gt;
&lt;p&gt;I’m able to trace my interest in computers and technology as far back as the 3rd grade. Sure, there was the glory of &lt;span class=&quot;small-caps&quot;&gt;Sega Genesis&lt;/span&gt; that came before that, but what kid isn’t in awe of video games? No, it was that time in the 3rd grade when every student was assigned a &lt;span class=&quot;small-caps&quot;&gt;Year-long project&lt;/span&gt;. We were to select any subject we could think of. Then, periodically throughout the year, we were to do a variety of research and projects related to that subject. At the end of the year, there was a fair where all of the students displayed their work. I had no idea what subject to pick. My father, in one of his famously creative and wise moments, suggested — with a smile on his face — that I should study &lt;span class=&quot;small-caps&quot;&gt;The Internet&lt;/span&gt;. I knew this had something to do with computers and that was enough; I said yes.&lt;/p&gt;
&lt;p&gt;Of the things I remember in the project a few are worth mentioning. It was 1998. We had 56k dial-up. My Dad took me to visit an &lt;abbr class=&quot;acronym&quot;&gt;ISP&lt;/abbr&gt;. At that time, our area had not yet succumbed to relying on giant corporations for internet access. The ISP we visited was operated out of an old house by what appeared to be a single person. The only thing that I remember about the visit is that the guy at the &lt;abbr class=&quot;acronym&quot;&gt;ISP&lt;/abbr&gt; asked me “Would you like to see &lt;span class=&quot;small-caps&quot;&gt;The Internet&lt;/span&gt;?” His question implied that if I could see it then I might possibly be able to understand what it was. My heart leaped and I was able to mumble something that sounded affirmative, so the man opened a closet in the house to reveal a rack of network switches with cables strewn about, all awash in the glow and flicker of LED lights. I likely just stared and drooled as he said things I didn’t understand before closing the door. The encounter was characteristic of what would fuel my ongoing interest — a combination of &lt;span class=&quot;small-caps&quot;&gt;Sci-Fi&lt;/span&gt;, awe, wonder, and not having any idea how the things that I was looking at were able to do what they did.&lt;/p&gt;
&lt;p&gt;For the finale of my &lt;span class=&quot;small-caps&quot;&gt;Year-long project&lt;/span&gt;, I provided input to my Dad as he built a website for me complete with a page that described the things that I liked to do, a guestbook, and animated GIFs. It was hosted on &lt;span class=&quot;small-caps&quot;&gt;Angelfire&lt;/span&gt; and created with &lt;a href=&quot;https://en.wikipedia.org/wiki/NetObjects_Fusion&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span class=&quot;small-caps&quot;&gt;NetObjects Fusion&lt;/span&gt;&lt;/a&gt;. The small glimpses of HTML that I got would never fully leave my consciousness.&lt;/p&gt;
&lt;p&gt;Despite some very geeky moments early on though, I never thought I could be a programmer. There was too much mystique around it and I didn’t have enough confidence in my aptitude to think that I might be able to ever do that myself. For many years I got my kicks from reading &lt;span class=&quot;small-caps&quot;&gt;PC Gaming&lt;/span&gt; magazine, spending whole summers downloading shareware games, and making my own software distribution that I gave to classmates. Of course, things changed significantly when I was put on a software development team for an 8-month rotation at one of my first jobs after undergrad.&lt;/p&gt;
&lt;p&gt;I was working at that conservative regional bank that I mentioned earlier. They had a program where they hired new grads and put them through three 8-month rotations in different departments of the IT organization before placing them somewhere permanently. As I said before, I never thought I could be a programmer, but the kind HR rep told me on my first day that I was being placed on an &lt;span class=&quot;small-caps&quot;&gt;Agile&lt;/span&gt; software development team for my first 8 months and my only goal was to learn. The open-ended goal, my 20 years of accumulated curiosity, and the mentor I was assigned were enough to get over the confidence hump and find joy in making software.&lt;/p&gt;
&lt;p&gt;I quickly fell in love with being on a team of geeks, trying to figure out what to build as we built it. There was a sort of geek religion that we all observed in that open office. The great Sci-Fi films were our Old Testament and &lt;span class=&quot;small-caps&quot;&gt;Clean Code&lt;/span&gt; was our New Testament. Like any good religious community, we debated solutions to the problem of evil and the ever-present issue of how to practice our daily liturgies (let the reader understand: &lt;span class=&quot;small-caps&quot;&gt;Vim&lt;/span&gt; vs. &lt;span class=&quot;small-caps&quot;&gt;Emacs&lt;/span&gt;). The deed was done and I was now to do this work professionally.&lt;/p&gt;
&lt;h2&gt;The Nature of the Work&lt;/h2&gt;
&lt;p&gt;There are two sides to the coin of &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; that acted in tandem to bring me to full devotion. First, there are worlds upon worlds of abstractions, architecture, tools, methods, and patterns that one can get lost in. I call this part of the work &lt;span class=&quot;small-caps&quot;&gt;Engineering&lt;/span&gt;. Second, there is the harder-to-describe work of first, understanding your users and their world, and second, bringing your skills to bear upon their problems. I use the term &lt;span class=&quot;small-caps&quot;&gt;Development&lt;/span&gt; for this part of the work. At their best, these seemingly disparate disciplines interplay healthily and produce an emergent effect that I think of as &lt;span class=&quot;small-caps&quot;&gt;Craftsmanship&lt;/span&gt;. The first two are what one spends their time on. The latter becomes &lt;span class=&quot;small-caps&quot;&gt;The Infinite Game&lt;/span&gt;.&lt;/p&gt;
&lt;h3&gt;Engineering&lt;/h3&gt;
&lt;p&gt;Early on in my 8 months with the &lt;span class=&quot;small-caps&quot;&gt;Agile&lt;/span&gt; software development team, someone walked me through the codebase of an app that an adjacent team had been working on. It was built with &lt;span class=&quot;small-caps&quot;&gt;Spring&lt;/span&gt; &lt;abbr class=&quot;acronym&quot;&gt;MVC&lt;/abbr&gt;. At that point, I had never heard of &lt;abbr class=&quot;acronym&quot;&gt;MVC&lt;/abbr&gt; before, so it was an exercise in explaining the difference between the front-end, the back-end, how the controllers interacted with models, etc. I remember the feeling of excitement just from being shown how the different layers of abstraction handled different concerns. There is a thrill in seeing how something works. I think for people like me whose formative years were less connected with nature and using one’s hands to make something, there is a way in which this type of engineering is fulfilling. It’s also an escape. There are entire technical worlds to get lost in. One’s present social issues can fade into the background when you’re comparing architectural approaches or ways to represent your data.&lt;/p&gt;
&lt;p&gt;Some people probably live more fully in the world of &lt;span class=&quot;small-caps&quot;&gt;Engineering&lt;/span&gt; than I do. For me, it’s an (interesting) means to the end of providing value in the real world.&lt;/p&gt;
&lt;h3&gt;Development&lt;/h3&gt;
&lt;p&gt;I think of a software project as an endeavor to create a product. We start with a diverse set of problems, ideas, research, analyses, and hunches. Over time the team processes those raw materials into a new creation — a semi-tangible system or product is brought into existence. And now, this new thing invites users into an experience or encounter that is perhaps somewhat unique from all that existed before it. It may solve a problem or only exist as a means of enrichment. Discovering what to make is the journey and the moments of joy or adventure along the way usually make it worth the price of admission.&lt;/p&gt;
&lt;p&gt;The goal of &lt;span class=&quot;small-caps&quot;&gt;Development&lt;/span&gt; is of course to produce something valuable. In my experience though, we tend to underestimate the value that is inherent in the journey itself. In some cases, the value provided to the business is just as much in the understanding that comes from trying to figure out what to build as it is in the result itself. Software often has to codify processes and practices that may have been implicit until now. &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; requires us to understand the process and transform it. Beyond merely identifying a process, digitizing a process forces us to change how it works. Richard Hamming summarizes this well. He’s comparing aspects of the industrial revolution to the digital revolution:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Indeed, one of the major items in the conversion from hand to machine production is the imaginative redesign of the &lt;em&gt;equivalent product&lt;/em&gt;. Thus in thinking of mechanizing a large organization, it won’t work if you try to keep things in detail exactly the same, rather there must be a larger give and take if there is to be a significant success. &lt;strong&gt;You must get the essentials of the job in mind and then design the mechanization to do that job rather than trying to mechanize the current version — if you want a significant success in the long run&lt;/strong&gt;.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Making software is a process that forces people to learn about the nature of a thing in the real world to the point where they can create a digital experience that interfaces with reality. Learning about the nature of a thing and representing it — even improving it — are skills in their own right. &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; as a means of learning and discovery is renewable motivational fuel for me. I suppose that’s why I keep moving towards working in domains that I’m personally interested in.&lt;/p&gt;
&lt;h3&gt;Craft&lt;/h3&gt;
&lt;p&gt;I then think of &lt;span class=&quot;small-caps&quot;&gt;Craft&lt;/span&gt; as a property that emerges from the &lt;span class=&quot;small-caps&quot;&gt;Engineering&lt;/span&gt; and &lt;span class=&quot;small-caps&quot;&gt;Development&lt;/span&gt; disciplines. There is a thrill in the &lt;span class=&quot;small-caps&quot;&gt;Engineering&lt;/span&gt; and a joy in the &lt;span class=&quot;small-caps&quot;&gt;Development&lt;/span&gt;. When rightly held together I find that care, pride, enjoyment, and beauty begin to inform the way that I work.&lt;/p&gt;
&lt;h4&gt;Make it work, make it right, make it beautiful&lt;/h4&gt;
&lt;p&gt;Due to the influence of those I was working with, I learned early on that &lt;span class=&quot;small-caps&quot;&gt;Making it work&lt;/span&gt; is only the first step of an engineering process. After it works it is just as important to &lt;span class=&quot;small-caps&quot;&gt;Make it right&lt;/span&gt;. In those early days, I remember spending whole afternoons finding the &lt;em&gt;right&lt;/em&gt; way to implement something long after we had it working. This was likely when I first caught a whiff of &lt;span class=&quot;small-caps&quot;&gt;Craft&lt;/span&gt;. The programmer who is finished when it &lt;em&gt;works&lt;/em&gt; has stopped short. There are limitless ways to implement something but some implementations are objectively worse than others once you start thinking about scaling, maintainability, and (gasp!) beauty. When I started caring about being able to do the work rather than progressing my career — when I started finding systems, code, and my tools beautiful — that’s when &lt;span class=&quot;small-caps&quot;&gt;Craft&lt;/span&gt; emerged. Now admittedly, my sense of aesthetics related to being a programmer is somewhat intense compared to that of others. I remember a season when I was almost exclusively writing CoffeeScript in Vim — unicode that rolled off my fingers into my modal editor was so terse and expressive that it seemed to be valuable in and of itself. More than once I felt more like a poet than a programmer in that season.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;small-caps&quot;&gt;Craft&lt;/span&gt; is about more than aesthetics though. When it takes hold you find a strange commitment within yourself to the work. The concept of &lt;span class=&quot;small-caps&quot;&gt;The Long Road&lt;/span&gt; characterizes this well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;People aspiring to become masters of software craftsmanship need to plan for the long term. This long (yet bright) journey will bring you a rich set of abilities. You will become skilled at learning, problem-solving, and developing strong relationships with your customers. You will come to wield knowledge and technology as the samurai uses his short and long swords. You will come to comprehend and appreciate the deeper truths of software development. But all this will take time.&lt;/p&gt;
&lt;p&gt;You should be prepared for the length of this journey… you should keep in mind the expectation that you will be a working software developer even when you are middle-aged. Let this influence the jobs you take and the scope of your ambitions. If you’re still going to be working in 20 years, then you can do anything. No one is so far ahead that you can’t match their skill level given the decades you will have to hone your craft. No business or technical domain is closed to you… rather than counting the days to retirement, the craftsman will willingly and joyfully work into her final decades.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Creating&lt;/h2&gt;
&lt;p&gt;From a philosophical point of view, I believe “there’s nothing new, only fresh ways of combining old stuff.”&lt;sup&gt;&lt;a href=&quot;#user-content-fn-3&quot; id=&quot;user-content-fnref-3&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; As creatures ourselves everything we can do is derivative of the creation itself in some way that is impossible to disentangle. When &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; though, there is sometimes an undeniable sensation that not only is something being created or born in front of our eyes, but that we are a part of that process. Whether derivative or not, that sensation can be exhilarating.&lt;/p&gt;
&lt;p&gt;At its best, this amounts to a sense of mystery and wonder while one does the work — watching something be created from (seemingly) nothing all while not knowing how the experience will unfold. In what some considered a stuffy office job — surrounded by geeks, ugly office decor, and sub-par coffee — there is to be found creativity, joy, hope, expectation, uncertainty, and delight. And what makes &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; &lt;em&gt;the best&lt;/em&gt; is that when wielded carefully, these delights can be accessed almost daily. Early on I was struck by an excerpt from Frederick Brooks (emphasis mine) that captures what it can be like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God’s delight in making things, a delight shown in the distinctiveness of each leaf and each snowflake…&lt;/p&gt;
&lt;p&gt;The programmer, like the poet, works only slightly removed from pure thought-stuff. &lt;strong&gt;&lt;em&gt;He builds his castles in the air, from air, creating by exertion of the imagination.&lt;/em&gt;&lt;/strong&gt; Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures… Yet the program construct, unlike the poet’s words, is real in the sense that it moves and works, producing visible outputs separately from the construct itself. It prints results, draws pictures, produces sounds, moves arms. &lt;strong&gt;&lt;em&gt;The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.&lt;/em&gt;&lt;/strong&gt;&lt;sup&gt;&lt;a href=&quot;#user-content-fn-4&quot; id=&quot;user-content-fnref-4&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Fred Brooks, The Mythical Man-Month: Essays on Software Engineering&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the early months of my first gig, I watched as our team discovered what we should build and how we should build it &lt;em&gt;as we were building it.&lt;/em&gt; My mentor showed me both in microcosm and macrocosm that one often has to make something to figure out what should be made. This discovery by way of making was fractal — that is, it appeared at every granularity of the project. Out of thin air, I watched the castle be designed and built simultaneously and I was one of the wizards doing it, all while surrounded by post-it notes, aging Herman-Miller chairs, and bad coffee (have I mentioned the coffee was &lt;em&gt;really&lt;/em&gt; bad?). Working like a wizard while surrounded by people who thought it was just as much fun as I did? Surely, I had stumbled upon some sort of secret life cheat code that enabled work to be fun and delightful.&lt;/p&gt;
&lt;h2&gt;Craving&lt;/h2&gt;
&lt;p&gt;Outside of &lt;span class=&quot;small-caps&quot;&gt;Identity&lt;/span&gt;, &lt;span class=&quot;small-caps&quot;&gt;The Nature of the Work&lt;/span&gt; and &lt;span class=&quot;small-caps&quot;&gt;Creating&lt;/span&gt;, there is at least one more category of experience that is worth talking about. When one is engrossed in the work, there is another plane of delight that intersects with these other categories. This final experience is very circular. It’s something akin to a machine whose purpose is to create fuel for itself. It’s a regenerative motivation that creates… motivation. As we create we are enmeshed in &lt;a href=&quot;https://www.geepawhill.org/2019/11/15/ramps-rhythm-is-tension-and-release/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;rhythms of tension and release&lt;/a&gt;. We create tension when we write some code not knowing if it will do what we want it to. The release comes when it works. Sometimes we stack tension upon tension to get a hit of combined releases. As GeePawHill explains,&lt;sup&gt;&lt;a href=&quot;#user-content-fn-5&quot; id=&quot;user-content-fnref-5&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; humans exploit this sort of rhythm in music, TV show plotlines, and more.&lt;/p&gt;
&lt;p&gt;From my earliest moments as a software developer, I remember experiencing these concentric cycles of tension and release. Take for instance the one actual programming class that I had in school, &lt;span class=&quot;small-caps&quot;&gt;Java Software Development for Business Majors&lt;/span&gt;. Even in taking the class, there was an immediate onset of tension. Externally, there were the swirling rumors that this was a class that many before had failed. The professor was teaching remotely that semester and would mostly just give assignments on a glorified piece of forum software. I was but one of 30 or so non-programmer guppies taking the class; surely I wouldn’t get much help from my classmates. Internally, I had a lifelong interest in computers and the internet, but never felt as though I was smart enough to be a programmer. In light of all this, would I be able to teach myself to program to avoid failing the course, my schooling, and surely life? The tension was palpable. Just as palpable as the tension though, were those moments of resolution — getting a bit of code to &lt;em&gt;compile&lt;/em&gt; and consequently not feeling like failure in the moments before the flash of joy subsided. I often wondered if programming worked like an addiction for me. Each cycle of tension and resolution only led to a greater anticipation of the next.&lt;/p&gt;
&lt;p&gt;I learned that going through the gauntlet of &lt;span class=&quot;small-caps&quot;&gt;getting something to work&lt;/span&gt; involved a loop of tension and release that seemed to engender the desire for another, perhaps larger loop. &lt;span class=&quot;small-caps&quot;&gt;Making Software&lt;/span&gt; was a chase of some sort filled with miniature instances of these tension and release loops. I find that when I can get properly plugged into a task or solving a problem, &lt;span class=&quot;small-caps&quot;&gt;Space-Time&lt;/span&gt; itself melts away as I focus on reaching a solution. As I write code, loops of tension are opened and it’s my job to close them. When I do get there, it all just makes me want to do it again. Shepherding these cycles is likely very important for sustained motivation and productivity but it’s also just really enjoyable. Some of the moments that remain most fond to me are when the time available in an afternoon seemingly evaporates as I enter flow — letting go of almost all my other cares — to load up the problem and the system into mental RAM and cravingly chase the solution. In all my feeble encounters with the humanities, one that has stuck with me is T. S. Eliot’s reflections on &lt;span class=&quot;small-caps&quot;&gt;Time&lt;/span&gt; in &lt;em&gt;Burnt Norton&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Time past and time future&lt;br /&gt;
Allow but a little consciousness.&lt;br /&gt;
To be conscious is not to be in time&lt;sup&gt;&lt;a href=&quot;#user-content-fn-6&quot; id=&quot;user-content-fnref-6&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The craving pursuit of &lt;span class=&quot;small-caps&quot;&gt;Making it work&lt;/span&gt; is often a journey into the act of creating so deep that one becomes conscious and therefore exits time, for a time.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 id=&quot;footnote-label&quot; class=&quot;sr-only&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Hamming, Richard. &lt;em&gt;The Art of Doing Science and Engineering: Learning to Learn&lt;/em&gt;. Stripe Press, p. 19 &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;Hoover, Dave and Oshineye, Adewale. &lt;em&gt;Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman&lt;/em&gt;. O’Reilly, 2010. p. 39 &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-3&quot;&gt;
&lt;p&gt;“I think a lot of liberal arts education (and not just in music) gets it wrong by telling to the students to “be themselves.” There’s nothing new, only fresh ways of combining old stuff. If you are in an academic environment, students should just go to the library a lot” Ethan Iverson, &lt;em&gt;Twitter&lt;/em&gt;, 3 December, 2022 &lt;a href=&quot;https://twitter.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Link&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-3&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-4&quot;&gt;
&lt;p&gt;Brooks, Frederick P., Jr., &lt;em&gt;The Mythical Man-Month: Essays on Software Engineering&lt;/em&gt;. Addison-Wesley, 1982. &lt;a href=&quot;#user-content-fnref-4&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 4&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-5&quot;&gt;
&lt;p&gt;See &lt;a href=&quot;https://www.geepawhill.org/2019/11/15/ramps-rhythm-is-tension-and-release/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RAMPS - Rhythm is Tension and Release&lt;/a&gt;. &lt;em&gt;Rhythm&lt;/em&gt; is one of the &lt;a href=&quot;https://www.geepawhill.org/2017/09/05/a-sense-of-urgency-ramps-as-a-motivation-model/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;five&lt;/a&gt; “drives” that he identifies as essential for motivation. &lt;a href=&quot;#user-content-fnref-5&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 5&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-6&quot;&gt;
&lt;p&gt;Eliot, T. S. &lt;em&gt;Four Quartets&lt;/em&gt;. New York, Harcourt, Brace and Co, 1943. &lt;a href=&quot;#user-content-fnref-6&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 6&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Heroes and Housekeeping</title><link>https://mikebrinker.net/blog/heroes-and-housekeeping</link><guid isPermaLink="true">https://mikebrinker.net/blog/heroes-and-housekeeping</guid><description>Balancing long-term projects and short-term demands</description><pubDate>Thu, 20 Feb 2020 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I came across an &lt;a href=&quot;https://doist.com/blog/heroes-housekeeping-days/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;interesting article&lt;/a&gt; over at the Doist blog. It seems their front-end team highly values Deep Work, but was having trouble balancing this with production support demands that would arise. They arrived at a solution that looks a lot like my &lt;a href=&quot;https://mikebrinker.net/blog/one-hand-approach-to-production-support/&quot;&gt;One-Hand Approach to Production Support&lt;/a&gt; where each month, a “hero” is set aside from the team to focus on handling urgent issues. Here’s a bit from the article:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Each month one person on each product team becomes the “Hero”. Their main responsibilities are to communicate with the support team, triage bugs, file them in our bug tracker, and fix the most urgent ones. On top of those tasks, the Hero takes care of smaller platform parity improvements, to ensure that our various apps don’t diverge too much, as well as refactorings, to improve the general health of our code base.&lt;/p&gt;
&lt;p&gt;That’s a lot of work for one person. It’s a very reactive, communication-heavy role that can get stressful, particularly after a new feature is released. That’s why we rotate the role on a monthly basis.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;While in my experience one week was plenty of time playing the hero, the general purpose of the role is similar to what I have seen work. One person is sacrificed to deal with distractions for a time in order to protect the productivity of the rest of the team.&lt;/p&gt;</content:encoded></item><item><title>Flatten the Cost-of-Change Curve, you must.</title><link>https://mikebrinker.net/blog/the-cost-of-change</link><guid isPermaLink="true">https://mikebrinker.net/blog/the-cost-of-change</guid><description>A healthy codebase is inexpensive to change.</description><pubDate>Thu, 30 Jan 2020 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In software development, there is a key success factor that often goes unnamed. It lies below many debates that software teams have and is at the root of many failure and success stories. Kent Beck aptly described this factor in the early chapters of the first edition of his &lt;em&gt;Extreme Programming Explained&lt;/em&gt; book. In my experience developers and managers are unlikely to have read this book so I’m here doing my best to accurately convey them. This thinking is not original to me.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;First, let me attempt to express the essence of the idea:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A software system’s cost of change is inversely proportional to its potential ongoing economic advantage.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In argument form, it might look like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Software is a highly malleable medium&lt;/li&gt;
&lt;li&gt;Software’s ability to change is a primary competitive advantage&lt;/li&gt;
&lt;li&gt;Therefore, consistently low cost of change is essential to maximizing its intrinsic benefits&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s take a look at each point of the argument.&lt;/p&gt;
&lt;h2&gt;Software is a highly malleable medium&lt;/h2&gt;
&lt;p&gt;Software has induced a revolution into our world that is on the order of the printing press. We now interface with all the domains of our lives with the help of software. Nearly everything we create and consume is aided or mediated by software.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;Software itself is highly malleable which allows its output to likewise be very pliable.&lt;/p&gt;
&lt;p&gt;There are many angles to this (sociological, economical, cultural, etc…) but it seems to me that a key factor is how easy it can be to change software and thus modify its output. Costs associated with changing software (including time) differ from other media by orders of magnitude.&lt;/p&gt;
&lt;h2&gt;Software’s ability to change is a primary competitive advantage&lt;/h2&gt;
&lt;p&gt;Software has taken the world by storm precisely because it can be so malleable at such a low cost.&lt;/p&gt;
&lt;p&gt;Double-entry accounting done on paper includes an enormous amount of work if something changes once calculations are made. With software, the change is easy and thus the recalculations are automatic.&lt;/p&gt;
&lt;p&gt;Yes, submitting information digitally rather than physically reduces errors (by validating input) and slashes delivery costs, but at the end of the day the value of a digital submission process is in how easy it is to change. Adding a new validation rule, requiring a different type of information or adding a review process is relatively inexpensive to implement once a system is up and running.&lt;/p&gt;
&lt;p&gt;Publishing is another industry revolutionized by software. Just think about the difference between publishing updates to an ebook compared to printing the second edition of a physical book.&lt;/p&gt;
&lt;p&gt;It is economically “better” to employ software for a given task precisely because it can be so easy to modify and update.&lt;/p&gt;
&lt;h2&gt;Therefore, consistently low cost of change is essential to maximizing its intrinsic benefits&lt;/h2&gt;
&lt;p&gt;So, how is this discussion relevant to an individual software developer or a software team?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To achieve these economic advantages, software must &lt;em&gt;remain&lt;/em&gt; inexpensive to change.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We all know that possibly the most common problem to crop up in software teams is that as a codebase or system ages and gains more functionality it becomes very difficult to change. If code isn’t clean and readable and if relevant tasks aren’t documented and automated, making small changes to the system can take inordinate amounts of time and effort. This can be magnified by having a multiplicity of contributors who may come and go, each knowing a part of the system better than the whole. As functions get longer, if statements are added, comments become stale, and files get huge, a system loses the economic benefits that made it profitable in the first place.&lt;/p&gt;
&lt;p&gt;In light of this, software teams must focus on keeping their products’ cost of change consistently low.&lt;/p&gt;
&lt;p&gt;There is an ever growing pool of tools and methods to achieve this. Test-driven development, automated checks, automatic code styling, lint rules, CI jobs, &lt;a href=&quot;https://mikebrinker.net/blog/regular-dependency-updates/&quot;&gt;keeping your dependencies up to date&lt;/a&gt;, and code review processes are among some of the most prominent.&lt;/p&gt;
&lt;p&gt;If a software team fails to keep the cost of change low (“not enough time!”, “I can do that later”, “We don’t really need that yet”) they are really just biding their time until the next expensive rewrite.&lt;/p&gt;
&lt;h4&gt;If a team cannot exercise discipline to manage the cost of change, as a wise man once said, &lt;a href=&quot;https://getyarn.io/yarn-clip/609961ff-f41a-4056-8368-f87e438c3eb1#/OT5Cc0Nu3m&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;“then the Emperor has already won”&lt;/a&gt;.&lt;/h4&gt;</content:encoded></item><item><title>Healthy Codebase Habit: Regular Dependency Updates</title><link>https://mikebrinker.net/blog/regular-dependency-updates</link><guid isPermaLink="true">https://mikebrinker.net/blog/regular-dependency-updates</guid><description>Keep your team, project, and personal development healthy by updating your codebase&apos;s dependencies at a regular interval.</description><pubDate>Fri, 13 Dec 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Do you have a habit of updating your team’s dependencies? Congratulations, you’ve got &lt;strong&gt;fresh&lt;/strong&gt; dependencies.&lt;/p&gt;
&lt;p&gt;Do you lack a habit of upgrading your projects dependencies? Oh man, you’re dependencies are probably &lt;strong&gt;stale&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I’ve learned that it’s better in almost every way to regularly update your dependencies. Read on for more.&lt;/p&gt;
&lt;h2&gt;Stale Dependencies&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Stale dependencies lead to suffering.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;This is your team on stale dependencies&lt;/h3&gt;
&lt;p&gt;Everyone can guess what happens when you don’t keep your dependencies up to date on a project. Dependencies get out of date, then become harder and harder to upgrade. This is true, but there are actually deeper, darker problems to projects with stale dependencies.&lt;/p&gt;
&lt;p&gt;The first couple of projects that I worked on as a software developer did not value regular dependency updates. They were java projects in a large-ish IT organization. The progression went something like this:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;First, an approved version of a large framework was picked.&lt;/em&gt; This was usually at least the n - 1 version. From here the project began and dependencies would begin to accumulate. There was very little discussion over the fact that as time passed the project dependencies would become more and more out date, but this was the case.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Next, a developer faced a problem and wished to solve it&lt;/em&gt;. A developer faces a problem and realizes that one of the project’s dependencies could easily solve the problem. They go to upgrade a dependency to use it’s new feature and spend a few days in dependency resolution &lt;a href=&quot;https://en.wikipedia.org/wiki/Sheol&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;sheol&lt;/a&gt; until they give up.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Then, the team accumulates an identity that is disconnected from its technology community.&lt;/em&gt; The team is stuck on old technology so why read about what is up and coming? Why contribute back to the open source community? Why spend time thinking about ways we can improve and new patterns we can adopt?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Finally, much toil is had and the cycle repeats.&lt;/em&gt;  Silly workarounds solve problems rather than new patterns available latest dependencies. One broken window turns into 50. Eventually a new project needs to be funded to bring the app into a usable state again.&lt;/p&gt;
&lt;p&gt;All in all, stale dependencies cut a team off from its community and the valuable feedback loops contained therein. They incur large costs down the line and make daily life on a software development team less enjoyable.&lt;/p&gt;
&lt;h3&gt;Some problems with stale dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Major frameworks lock you into a specific version&lt;/li&gt;
&lt;li&gt;Difficulties resolving dependencies that have desired features&lt;/li&gt;
&lt;li&gt;Team becomes a disconnected user of the dependencies they use
&lt;ul&gt;
&lt;li&gt;unable to contribute back to the community&lt;/li&gt;
&lt;li&gt;unable to take advantage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cost of modifying product becomes so high, a new project must be funded to upgrade the app once it becomes a security concern or liability&lt;/li&gt;
&lt;li&gt;All of these negative side effects increase cost in sundry ways&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Fresh dependencies&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Fresh dependencies breed new feedback loops&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;This is your team on fresh dependencies&lt;/h3&gt;
&lt;p&gt;If you haven’t worked on a project that prioritized fresh dependencies, you may not be aware of the advantages that spring up. I myself was surprised.&lt;/p&gt;
&lt;p&gt;After spending a while on Java projects with stale dependencies, I joined a team in Javascriptland. In Javascriptland, ‘new’ things were happening so often that the team’s evergreen app would become unworkable from an engineering point of view if they didn’t regularly keep dependencies fresh. When I first joined the team I was surprised at how much the codebase was constantly improve. I eventually identified &lt;em&gt;fresh dependencies&lt;/em&gt; as a core practice that enabled these feedback loops.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Dependency updates signal the misuse of frameworks, libraries, and APIs as breaking changes were encountered.&lt;/em&gt; Dependency maintainers regularly find ways that the APIs of their projects are miused or underused. To counter this, they make deprecations and modify the way the dependency should be consumed. Watching these changes happen makes a team aware of things maintainers are doing to improve their product. Often, seeing this happen is infectious and spurs the improvement of internal APIs or even the overall adoption of say functional programming principles over the imperative. Immutability can be contagious.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Constantly improving lint rule sets help developers improve their codebases.&lt;/em&gt;  If you work in Javascriptland you should definitely be taking advantage of establish lint rulesets like the famous &lt;a href=&quot;https://github.com/airbnb/javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Airbnb&lt;/a&gt; repo. Upgrading these rulesets along with your dependencies will often introduce new rules that break your build. Taking time to explore why these rules were introduced and how you can follow them will lead you down new avenues of improving your codebase and programming practices. As the community learns, you learn.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Updating your language/runtime helps you to take advantage of new language features.&lt;/em&gt; Typescript is a great example of this. With typescript, if your regularly update to the latest stable version and read the blog post they produce explaining new features, you are incrementally learning about what will become part of the javascript spec in the next 12 months. Your codebase is able to take advantage of these features right away and you are using them as soon as they come out.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Proactively upgrading dependencies preemptively removes potential blockers.&lt;/em&gt; Rather than finding out you can’t use some feature that you need or that you will have to migrate a bunch of old code to maintain platform support, you will be ahead of the curve on the platforms, frameworks and libs that you use. No more worrying about running out of time to upgrade before something breaks in production.&lt;/p&gt;
&lt;h3&gt;Some advantages to fresh dependencies.&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dependency updates signal the misuse of frameworks, libraries, and APIs as breaking changes were encountered&lt;/li&gt;
&lt;li&gt;Constantly improving lint rule sets help developers improve their codebases&lt;/li&gt;
&lt;li&gt;Updating your language/runtime helps you to take advantage of new language features&lt;/li&gt;
&lt;li&gt;Proactively upgrading dependencies preemptively removes potential blockers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;In Sum&lt;/h2&gt;
&lt;p&gt;Keep your team, project, and personal development healthy by updating your codebase’s dependencies at a regular interval. Like our health or our relationships, doing good things often yields unpredictable benefits, while neglecting them will create emergency situations and make you feel like a lame human being.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Please share in the comments: advantages you have seen from keeping dependencies up to date, or stale dependency horror stories you’ve lived through.&lt;/p&gt;</content:encoded></item><item><title>&apos;Who You Are&apos; is &apos;What You Do&apos;</title><link>https://mikebrinker.net/blog/who-you-are-is-what-you-do</link><guid isPermaLink="true">https://mikebrinker.net/blog/who-you-are-is-what-you-do</guid><description>Motivation fuels methods and methods birth products. It is a mistake to think that we can avoid thinking about values and just &apos;deliver&apos; software.</description><pubDate>Sat, 27 Jul 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the the time that I’ve spent developing software so far in my life, I’ve seen a tendency for folks to create a false dichotomy – a dualism – between accomplishing goals (“pragmatism”) and desiring to accomplish them in the theoretical ‘best way’ (“idealism”). Alas, &lt;em&gt;logic abhors a dualism&lt;/em&gt; and it’s my experience that as soon as you begin creating such a dichotomy, you’ve fallen into a trap. In fact, I’m about to tell you that &lt;em&gt;who you are&lt;/em&gt; (the way you do things and your motivation) is inextricably connected to the things you produce (goals you achieve).&lt;/p&gt;
&lt;p&gt;Let’s look at this first through the lens of organizations and the products they produce. I’ve often seen that when a cultural problem exists in a company (selling things before they exist, not allowing employees to balance their work and life appropriately, favoring results above all else, etc) there is a desire to deliver and fix the cultural problems later. What many do not realize though is that the products produced by a culture are born in that context and bear the mark of their origin. In the same way that &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_law&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Conway taught us that the shape of an organization impacts the architecture of a system&lt;/a&gt;, we can learn that an organization’s motives shape its methods, and those methods produce a product that resembles its maker.&lt;/p&gt;
&lt;p&gt;Step back for a moment and consider this at the personal level. We often are driven to set goals for ourselves with the hope that once we accomplish said goal, we will have proof that we have become the person that we want to be (a marathon runner, someone with impecible hygiene, etc). James Clear, in his recent book &lt;em&gt;Atomic Habits&lt;/em&gt;, goes to great lengths to show that it is the journey towards a goal that shapes us, not the completion of a goal. One golden quote from the book is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://jamesclear.com/identity-votes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Every action you take is a vote for the type of person you wish to become.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The way you do things shapes who are you, and your identity – your heart – is what drives your actions.&lt;/p&gt;
&lt;p&gt;Now consider this from the software development point of view. Those who buy into the false dichotomy between ideals and results will say things like “we don’t need TDD, we need to ship software” or more perversely “Let’s wait to start using TDD until we get this first release out.” (You can exchange “TDD” in those phrases for other methods such as Continuous Delivery or Evolutionary Database Design) Those who understand that picking only ideals or results is a false choice will realize that “we can only deliver our first release and respond to change if our software can be safely modified”. In fact, favoring results over ideals is itself an ideal. There is no escaping the fact that your value system breeds a culture which births your products. Methods will always come out of ideals or vision, it’s just a matter of what ideal you choose to embrace.&lt;/p&gt;
&lt;p&gt;Once an individual developer, team, or organization understands this, there is a freedom that will arise. They will realize that they can take time to think about how they do things, in fact, they must think about the &lt;em&gt;how&lt;/em&gt;. There are times when it is profitable to slow down and reason about something out of your organization vision rather than a desire to achieve a goal by a certain date.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Don’t agree? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>The Software Developer&apos;s Path to Wisdom</title><link>https://mikebrinker.net/blog/wisdom-path</link><guid isPermaLink="true">https://mikebrinker.net/blog/wisdom-path</guid><description>A description of the stages one undergoes when adopting a proposition.</description><pubDate>Thu, 09 May 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Have you ever worked with someone who was seemed able to know the right thing to do in almost all situations? This person wasn’t only very good at solving technical problems but knew how to handle people, systems, and situations too. This was a person that possesed &lt;em&gt;wisdom&lt;/em&gt;. In this blog post I will set out to define wisdom and then present the way that I think about how someone becomes wise in a given domain.&lt;/p&gt;
&lt;h2&gt;Wisdom?&lt;/h2&gt;
&lt;p&gt;What is wisdom? There are many alternative defitions that you will encounter. First, let’s begin with what it isn’t:&lt;/p&gt;
&lt;p&gt;What wisdom is not:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Experience&lt;/li&gt;
&lt;li&gt;Old age&lt;/li&gt;
&lt;li&gt;Intellectual prowess&lt;/li&gt;
&lt;li&gt;Common sense&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any of the above factors may correlate to a wise person, but wisdom itself is something more. My definition:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Wisdom&lt;/em&gt; is the ability to understand reality and act accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Knowledge, experience, and emotional intelligence are all crucial to being able to apply wisdom, but on the whole wisdom comes across as that someone develops over time.&lt;/p&gt;
&lt;h2&gt;The Model (Brinker’s Model of Ideological Adoption?)&lt;/h2&gt;
&lt;p&gt;As I have thought about the acquisition of wisdom in my life and reflected on various environments in which I have sought it, I began to see a pattern. I noticed that whenever someone is presented with something new (an idea, tool, method, or system) there are stages of adoption which the person undergoes as they try that new thing out. For the sake of example, we’ll just call the thing in question “the new thing”. Here is what I’m calling the stages for now:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ignorance&lt;/li&gt;
&lt;li&gt;Awareness&lt;/li&gt;
&lt;li&gt;Zeal&lt;/li&gt;
&lt;li&gt;Wisdom&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Ignorance&lt;/h3&gt;
&lt;p&gt;The first stage, &lt;strong&gt;ignorance&lt;/strong&gt;, is when you are blissfully unaware of &lt;em&gt;the new thing&lt;/em&gt;. You haven’t heard of it. You may have experienced the problem that the new things solves but that’s about it.&lt;/p&gt;
&lt;h3&gt;Awareness&lt;/h3&gt;
&lt;p&gt;The second stage, &lt;strong&gt;awareness&lt;/strong&gt;, is when you become aware of &lt;em&gt;the new thing&lt;/em&gt;, but for whatever reason don’t attempt to apply it. Maybe you think it won’t be useful, or maybe you think it will be useful but that you don’t have time to try it out. Finally, you may be aware of &lt;em&gt;the new thing&lt;/em&gt; but don’t fully understand it.&lt;/p&gt;
&lt;h3&gt;Zeal&lt;/h3&gt;
&lt;p&gt;The third stage, &lt;strong&gt;zeal&lt;/strong&gt;, is a dangerous one. It could fairly be called the ‘cage stage’ because you should be locked in a cage until you are through it. In this stage you understand &lt;em&gt;the new thing&lt;/em&gt; to a degree and seek to apply it to every thing and every one, often yielding unfortunate results. You haven’t yet learned when &lt;em&gt;the new thing&lt;/em&gt; isn’t applicable, so you are an evangelist for it, blind to any situation where it isn’t useful and self-wise regarding its application. You know you are in this stage when you annoy friends/family/colleagues by blathering on and on about the glory of &lt;em&gt;the new thing&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Wisdom&lt;/h3&gt;
&lt;p&gt;The fourth stage, &lt;strong&gt;wisdom&lt;/strong&gt;, is the stage you want to be in. In this stage, the shininess has worn off a bit, and you are on a journey of knowing when not to use &lt;em&gt;the new thing&lt;/em&gt;. This stage asymptotically approaches perfection. You know you are getting here when you can find some aspect of &lt;em&gt;the new thing&lt;/em&gt; that you disagree with or could be a problem in some contexts. After the cage stage, this is where you become sane and tolerable regarding &lt;em&gt;the new thing&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Wisdom in Software Development&lt;/h2&gt;
&lt;p&gt;I have seen myself move through these stages at a macro level with regards to software development (and many other things) and also at a micro-level with certain tools, methods, and technologies. For a case study, let’s take a look at the way I adopted Test-Driven Development.&lt;/p&gt;
&lt;h2&gt;A Case Study: Test-Driven Development&lt;/h2&gt;
&lt;h3&gt;Ignorance&lt;/h3&gt;
&lt;p&gt;In college I had a programming class or two. No one ever mentioned TDD. I had no idea what it was. I did notice that the one programming project I had seemed to break often as I was changing it.&lt;/p&gt;
&lt;h3&gt;Awareness&lt;/h3&gt;
&lt;p&gt;In my first programming job I joined a team that lived and taught TDD. As soon as I began pairing with my team members I was introduced to the concept. It seemed like it might be helpful, but writing a program that tests the program which I’m writing felt very odd to think about. I always began coding a new feature and then heard one of my coworkers say “did you write a test for that?”. As I learned how to write tests and was introduced to mocks, stubs, and spies, I became proficient but still didn’t consistently write tests first.&lt;/p&gt;
&lt;h3&gt;Zeal&lt;/h3&gt;
&lt;p&gt;On my first software project as a full-fledged junior, I engaged in TDD with much zeal.&lt;/p&gt;
&lt;p&gt;Was I about to define a class? Write a test first.&lt;br /&gt;
Extracting something into a private method? Write a test first.&lt;/p&gt;
&lt;p&gt;Not only did I behave this way myself but I demanded that the team maintain a near 100% coverage rate.&lt;/p&gt;
&lt;p&gt;The result?&lt;/p&gt;
&lt;p&gt;The tests were brittle. The slightest refactor caused a lot of rework in the tests. We went to great lengths to test our getters and setters. Some teammates found me annoying.&lt;/p&gt;
&lt;h3&gt;Wisdom&lt;/h3&gt;
&lt;p&gt;I eventually realized that some of my tests provided no value. Testing getters and setters didn’t buy us much. And writing a test before defining a class? That was the essence of an overzealous junior developer. I scaled back a bit and focused on writing tests that the project &lt;em&gt;needed&lt;/em&gt;. Eventually I was even able to grok the difference between London and Detroit style TDD and understand where I fit in the scheme of things. At this point people could bear to hear me talk about TDD again. I was even able to mentor and help a few people figure it out along the way. I’m not a zen master by any means, but the benefits that TDD provides as a tool are clear to me and I also understand when it isn’t that helpful. Now I remain on the long road of wisdom.&lt;/p&gt;
&lt;h2&gt;In Sum&lt;/h2&gt;
&lt;p&gt;Hopefully you see some concordance with reality in this model. It’s been a helpful tool for me to understand people and team dynamics in some cases.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Was this helpful in any way? Did I miss a step? Do you have a better name for this thing? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>A Software Engineering Manifesto</title><link>https://mikebrinker.net/blog/software-engineering-manifesto-2019</link><guid isPermaLink="true">https://mikebrinker.net/blog/software-engineering-manifesto-2019</guid><description>A snapshot of my best practices and preferences related to software engineering/development.</description><pubDate>Sat, 13 Apr 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Disclaimer: “Best practices” are less like objective truths and more like pragmatic successes in the software engineering field. This is not to say that the correct way or even &lt;em&gt;best&lt;/em&gt; way of doing something doesn’t exist, but rather given our finiteness and the external forces of the worlds we inhabit, one should expect some variability here. While I state these in the indicative sense (“X shall be Y”) at the end of the day, the best way to write and ship software will differ from context to context and will (hopefully!) look different in coming years.&lt;/p&gt;
&lt;h2&gt;Deployments Shall Be&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Automated&lt;/li&gt;
&lt;li&gt;Scheduled&lt;/li&gt;
&lt;li&gt;Repeatable&lt;/li&gt;
&lt;li&gt;Often&lt;/li&gt;
&lt;li&gt;While the system is in use&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Databases Shall Be&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Migrated automatically during deployments&lt;/li&gt;
&lt;li&gt;Locally accessible for developers&lt;/li&gt;
&lt;li&gt;Optimized just in time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Code Shall Be&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Version controlled&lt;/li&gt;
&lt;li&gt;Style-enforced at build time by automated tooling&lt;/li&gt;
&lt;li&gt;As simple as could possibly work&lt;/li&gt;
&lt;li&gt;Nearly comment free&lt;/li&gt;
&lt;li&gt;Deleted if unused&lt;/li&gt;
&lt;li&gt;Test-driven&lt;/li&gt;
&lt;li&gt;Treated as a liability&lt;/li&gt;
&lt;li&gt;Paired on as needed&lt;/li&gt;
&lt;li&gt;Deleted with joy&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Project Management Shall Be&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pull-based&lt;/li&gt;
&lt;li&gt;Optimized for end-results, not implementation details&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Developers Shall be&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Courageous to simplify the system in almost all circumstances&lt;/li&gt;
&lt;li&gt;Teliocentric in their efforts&lt;/li&gt;
&lt;li&gt;Mildly over-affectionate towards their text editors&lt;/li&gt;
&lt;li&gt;Allowed to work uninterrupted for generous amounts of time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;System Design Shall Be&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Evolving as necessary with every feature&lt;/li&gt;
&lt;li&gt;Changing as the team’s understanding of the problem domain changes&lt;/li&gt;
&lt;li&gt;Ultimately enforced at code review time&lt;/li&gt;
&lt;li&gt;Consistent whenever possible&lt;/li&gt;
&lt;li&gt;Delegated to widely-used open source implementations when possible&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;Did I miss something? Was I completely wrong in some way? Was there something I got right? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>An Atlas for Learning React</title><link>https://mikebrinker.net/blog/react-atlas</link><guid isPermaLink="true">https://mikebrinker.net/blog/react-atlas</guid><description>A guide to learning the concepts and ecosystem of react (a somewhat popular javascript library)</description><pubDate>Fri, 29 Mar 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Learning something like &lt;a href=&quot;https://reactjs.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;React&lt;/a&gt; takes time. For every excellent react resource that exists on the internet, there are several poorly written tutorials showing you how to make a todo list app. This ‘atlas’ serves as a guide for myself and others.
It will probably be updated over time.
Information found in the glossary of terms is largely indebted to the various resources mentioned here.&lt;/p&gt;
&lt;h2&gt;Conceptual Overviews&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org/docs/hello-world.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The official React guide to main concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://overreacted.io/react-as-a-ui-runtime/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;React as a UI Runtime&lt;/a&gt; (Learning react from first principles)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Tools&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://facebook.github.io/create-react-app/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Create React App&lt;/a&gt;, A CLI and set of sensible defaults for react projects&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/react-devtools&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;React devtools&lt;/a&gt;, Chrome and Firefox extension fo view react stuff along with dev tools&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Ecosystem&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nextjs.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Next.js&lt;/a&gt;, Server-side rendering&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://redux.js.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Redux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Tutorials&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org/tutorial/tutorial.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Official React Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://roadtoreact.com/course-details?courseId=THE_ROAD_TO_REACT_WITH_FIREBASE&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The Road to React with Firebase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;People&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://twitter.com/jordwalke&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Jordan Walke&lt;/a&gt;, creator of React&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://overreacted.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Dan Abramov&lt;/a&gt;, creator of Redux and Create React App&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Glossary of Terms&lt;/h2&gt;
&lt;h3&gt;Elements&lt;/h3&gt;
&lt;p&gt;React &lt;em&gt;elements&lt;/em&gt; are plain javascript objects that represent something that react will render in the DOM.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Treated as immutable by react&lt;/li&gt;
&lt;li&gt;Can reference valid DOM tags or user-created components&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Components&lt;/h3&gt;
&lt;p&gt;React &lt;em&gt;components&lt;/em&gt; functions or instances of classes that receive props and return elements.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can be as simple as a js function that receives an object and returns and element&lt;/li&gt;
&lt;li&gt;Can also be a class that extends &lt;code&gt;React.component&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Components start with an uppercase char&lt;/li&gt;
&lt;li&gt;Must not mutate props&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;State&lt;/h4&gt;
&lt;p&gt;&lt;em&gt;State&lt;/em&gt; is essentially a property on component classes that is accessible at &lt;code&gt;this.state&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Only mutate state using &lt;code&gt;setState&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setState&lt;/code&gt; is asynchronous&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setState&lt;/code&gt; merges properties shallowly&lt;/li&gt;
&lt;li&gt;state is local to a given component and uses a top-down data flow&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Mounting&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Mouting&lt;/em&gt; is when an element is rendered to the DOM for the first time&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Unmounting&lt;/em&gt; is when an element is removed from the DOM&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Lifecycle Methods&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;componentDidMount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;componentWillUnmount&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;Did you come across some excellent resources when learning React? Did you have a turning point where react suddenly ‘made sense’ to you? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>Linux, Entropy, Random Number Generation, and you</title><link>https://mikebrinker.net/blog/linux-entropy-rng</link><guid isPermaLink="true">https://mikebrinker.net/blog/linux-entropy-rng</guid><description>Random number generation is important in cryptography. Application developers: make sure you are using a randomness source that provides the needed level of performance.</description><pubDate>Sat, 09 Mar 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently while debugging a performance issue with a JRuby application, I learned that the JVM defaults to &lt;code&gt;/dev/random&lt;/code&gt; as its randomness source. This default resulted in a performance problem in the application. This post will cover the purpose of &lt;code&gt;/dev/random&lt;/code&gt; and &lt;code&gt;/dev/urandom&lt;/code&gt; in general, the cause of the performance problem that I experienced, and the solution that I landed on.&lt;/p&gt;
&lt;h2&gt;Why Random Number Generation (RNG) is important in computing&lt;/h2&gt;
&lt;p&gt;In most unix-like operating systems, the files located at the path &lt;code&gt;/dev/random&lt;/code&gt; and &lt;code&gt;/dev/urandom&lt;/code&gt; server as random number generators. True randomness is a concept that is very important in computing, especially with regards to cryptography. Cryptography often depends on a key or set of keys that are secret. If an actor was able to identify a pattern used to generate secret keys, they could likely find a way to guess what a secret key is. Inserting &lt;em&gt;randomness&lt;/em&gt; into the process of generating a secret key makes it harder for an actor to find a pattern in key generation.&lt;/p&gt;
&lt;p&gt;Think for a moment about how you might write a program that would generate random values. Perhaps the program could do some math on a seed value that results in integers produced that don’t appear to follow any particular pattern. But how does one select a seed? If there is a pattern in the seed used to generate random values then you haven’t accomplished much. One might resort to using a date or timestamp and then performing math to generate a seed but in that case the seed could be guessed easily enough.&lt;/p&gt;
&lt;p&gt;A source of true randomness would be quite valuable and quite difficult to construe.&lt;/p&gt;
&lt;h2&gt;Linux and RNG&lt;/h2&gt;
&lt;p&gt;To accomplish sufficiently random number generation, the linux operating system keeps an ‘entropy pool’ which is a collection of random values that one hopes to be unknown by some malevolent actor. The entropy pool then acts as a seed to a process that tries to ‘randomly’ generate numbers. This results in a stream of random output that is available at &lt;code&gt;/dev/random&lt;/code&gt; on the filesystem. The entropy pool is populated from a variety of sources like user input activity and other environmental noise that device drivers may observe.&lt;/p&gt;
&lt;p&gt;Things get a little complicated when the entropy pool runs low.&lt;/p&gt;
&lt;p&gt;When entropy runs low, &lt;code&gt;/dev/random&lt;/code&gt; stops or blocks. This causes any process requiring data from the random stream to wait until the entropy pool is full enough to continue generating random numbers. There is another randomness stream on most linux system at &lt;code&gt;/dev/urandom&lt;/code&gt; that does not block when the entropy pool runs low. Choosing not to block when the entropy pool runs low can be considered ‘less secure’ but one must think about the situations that can cause this to happen and judge accordingly whether or not &lt;code&gt;/dev/urandom&lt;/code&gt; is safe to use.&lt;/p&gt;
&lt;h2&gt;The JVM and /dev/random&lt;/h2&gt;
&lt;p&gt;By default, many versions of the JVM will default to using &lt;code&gt;/dev/random&lt;/code&gt;. Depending on the size of your entropy pool and your application’s need for random numbers, this can put you in a situation where you are blocked until the entropy pool reaches its required size.&lt;/p&gt;
&lt;p&gt;I noticed the performance problem when I modified a JRuby application to use stronger ciphers for TLS. Presumably the strong ciphers required more random input at times and the entropy pool on my servers wasn’t always up to the task. After doing some research, (I found &lt;a href=&quot;https://www.2uo.de/myths-about-urandom/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;this article&lt;/a&gt; to be helpful) I decided to use &lt;code&gt;/dev/urandom/&lt;/code&gt; for the needs of our application.&lt;/p&gt;
&lt;h2&gt;Addendum: Useful commands and config&lt;/h2&gt;
&lt;p&gt;Here are a few helpful commands and settings related to entropy pools in linux and configuring the JVM accordingly. The commands assume RHEL or another system like it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Available entropy: &lt;code&gt;cat /proc/sys/kernel/random/entropy_avail&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Does a CPU have a hardware RNG? &lt;code&gt;cat /proc/cpuinfo | grep -i rdrand | echo $?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;JVM flag for default randomness source: &lt;code&gt;-Djava.security.egd=file:/dev/urandom&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;Have you dealt with problems related to &lt;code&gt;/dev/random&lt;/code&gt;’s blocking behavior? Did I get something wrong here? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>Refactoring Doesn&apos;t Require Domain Knowledge</title><link>https://mikebrinker.net/blog/refactoring-without-domain-knowledge</link><guid isPermaLink="true">https://mikebrinker.net/blog/refactoring-without-domain-knowledge</guid><description>The code never lies</description><pubDate>Sun, 24 Feb 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I came across this great &lt;a href=&quot;https://twitter.com/GeePawHill&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;GeePaw Hill&lt;/a&gt; &lt;a href=&quot;https://twitter.com/GeePawHill/status/1099733643734470656&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;thread&lt;/a&gt; on twitter about refactoring and domain knowledge. The final tweet in the thread sums it up well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When I’m refactoring, I do my best work when I am entirely domain-blind, and am working with and thinking of all and only what the code that is actually there actually does. Prioritize reading code over studying the application domain.&lt;/p&gt;
&lt;p&gt;Have a pleasantly odd Sunday!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Over the years I have learned to trust the fact that &lt;em&gt;the code never lies&lt;/em&gt;. In addition to possibly saying some interesting things about epistemology, this aphorism has proven trustful to me time and time again. While devs (and others) &lt;del&gt;argue&lt;/del&gt; discuss what some code does, how it’s working, etc… in almost every case the wise thing to do is say very little and begin reading the code.&lt;/p&gt;
&lt;p&gt;There are lessons in this thread about the value of readable code as well. In the thread, there seems to be a correlation between the refactoring effort (making the code easier to understand) and the discovery of the performance problem. The easier code is to read, the easier it is to reason about, which enables developers to make improvements to it, or at very least decreases their chance of screwing it up as they change it. An explanation of the &lt;em&gt;value&lt;/em&gt; of clean (read: readable) code is worthy of its own post.&lt;/p&gt;
&lt;p&gt;Alas! The whole thread is a great read. &lt;a href=&quot;https://threadreaderapp.com/thread/1099733643734470656.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Read it unrolled&lt;/a&gt; on ThreadReader.&lt;/p&gt;</content:encoded></item><item><title>IDEs are dead. Long Live Development Environments. (Part 3)</title><link>https://mikebrinker.net/blog/build-a-development-environment</link><guid isPermaLink="true">https://mikebrinker.net/blog/build-a-development-environment</guid><description>Five steps to getting away from your IDE, mastering your tools, and building your own development environment.</description><pubDate>Sun, 10 Feb 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve already written about &lt;a href=&quot;https://mikebrinker.net/blog/step-away-from-your-ide/&quot;&gt;why you should step away from your IDE&lt;/a&gt; and &lt;a href=&quot;https://mikebrinker.net/blog/benefits-of-stepping-away-from-your-ide/&quot;&gt;how I’ve benefited from doing so&lt;/a&gt;. Now let’s take a look at how this can be accomplished. As always these steps are based on my experience as a finite human being and thus your mileage may vary. The five steps are:&lt;/p&gt;
&lt;h2&gt;1. Begin using a single tool directly, outside of your IDE.&lt;/h2&gt;
&lt;p&gt;The first step is begin interacting directly with one of the tools that your IDE abstracts.
Choose a tool, and make it a goal to only use it directly (rather than from inside of your IDE) from now on.
Use the interface that that the tool defaults to. For example, if you choose to use Git directly, use the command line interface rather than another third party client.
If nothing else you will gain the advantage of learning a particular tools in more depth. Some ideas for which tool to pick:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dependency Management&lt;/li&gt;
&lt;li&gt;Build System&lt;/li&gt;
&lt;li&gt;Version Control&lt;/li&gt;
&lt;li&gt;Test Execution / Coverage&lt;/li&gt;
&lt;li&gt;Code Quality / Linting Tools&lt;/li&gt;
&lt;li&gt;Application Servers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. Use all tools directly. Eventually only rely on the text editor in your IDE.&lt;/h2&gt;
&lt;p&gt;Repeat step one until you can use all or most of your development tools directly rather than through your IDE. The goal here is for the IDE to basically just become a text editor. At this point your development experience might feel slower than it was before, but what you lose in daily productivity will be rewarded in the long run with a better knowledge and command of your tools.&lt;/p&gt;
&lt;p&gt;This isn’t the place that you want to be long term, so work to get a good understanding of your tools quickly so that you can move onto steps 3 and 4.&lt;/p&gt;
&lt;h2&gt;3. Switch text editors.&lt;/h2&gt;
&lt;p&gt;Once you reach step two, you will most likely realize that your IDE is not a great text editor. It’s big, slow, and is most likely lacking advanced features that specialized text editors have. Now that you only really have your IDE because you need a text editor, it’s time to find a &lt;em&gt;your&lt;/em&gt; text editor. Finding the right text editor could be a blog series of its own, but here are a few things to think about.&lt;/p&gt;
&lt;p&gt;Finding &lt;em&gt;your&lt;/em&gt; text editor is what some will call a journey. Ideally you want something that has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cross platform support&lt;/li&gt;
&lt;li&gt;large online community&lt;/li&gt;
&lt;li&gt;customization capabilities&lt;/li&gt;
&lt;li&gt;staying power&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Text editors that have these qualities will like have a larger learning curve, but that’s ok! You spend hours of your life editing text &lt;em&gt;every day&lt;/em&gt;. Why not dig in and get good at it? I’m not the first one to say this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Use a Single Editor Well&lt;/p&gt;
&lt;p&gt;The editor should be an extension of your hand; make sure your editor is configurable, extensible, and programmable.&lt;/p&gt;
&lt;p&gt;(From &lt;em&gt;The Pragmatic Programmer)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;4. Slowly bring IDE functionality into your text editor.&lt;/h2&gt;
&lt;p&gt;This step always in progress for most developers. Once you are on the path to mastering your text editor, you will find it beneficial to begin adding little shortcuts to your editor to increase your productivity. For example, rather than switching to new terminal window to run your unit tests, write a macro (or something equivalent for your editor… perhaps a plugin?) that runs all tests in the visible file based upon a keystroke of your choice. Some ideas to enhance productivity in your editor:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A fuzzy finder for file contents or names&lt;/li&gt;
&lt;li&gt;Ability to see the VCS history for a given file&lt;/li&gt;
&lt;li&gt;A shortcut to automatically format markup (chunks of XML, JSON, etc…)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point I anticipate some objections. Why leave your IDE if the goal is just to rebuild it eventually?
There are two main reasons why bringing functionality back into your text editor is not just an insane re-doing of what you already had with your IDE.&lt;/p&gt;
&lt;p&gt;First, recognize that by this point you have gained an enhanced knowledge of all the tools in your toolkit and become a text editing wizard. Any shortcut you add back is added from a position of knowledge (of your tools) rather than dependence (on your IDE).&lt;/p&gt;
&lt;p&gt;Second, with this approach you only bring what modifications you need. You will end up with something much lighter than an IDE overall.&lt;/p&gt;
&lt;h2&gt;5. Build your environment.&lt;/h2&gt;
&lt;p&gt;Now that you are living and working with a set of development tools that you have glued together through your expert knowledge and experience, you can take it one step farther by noticing patterns in your daily development activities and automating those. For example, if you find yourself opening the same three terminal emulator tabs (and starting various tools in them) write a script that does that!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Terminal Emulator: Customized Windows, Tabs, and Panes&lt;/li&gt;
&lt;li&gt;A Tiling Window Manager: i3, xmonad, kwm, Amethyst&lt;/li&gt;
&lt;li&gt;Window Manager with the Terminal: Tmux, Tmuxinator, Screen&lt;/li&gt;
&lt;li&gt;Make your environment portable: Store your configurations on GitHub or create a docker image that houses all of your tools and their dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;This is how I broke my dependence on an IDE. Have you? Let’s hear how you did it in the comments.&lt;/p&gt;</content:encoded></item><item><title>All Web Abstractions Leak</title><link>https://mikebrinker.net/blog/all-web-abstractions-leak</link><guid isPermaLink="true">https://mikebrinker.net/blog/all-web-abstractions-leak</guid><description>Leaky abstractions make men old and grumpy</description><pubDate>Sat, 02 Feb 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://twitter.com/garybernhardt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gary Bernhardt&lt;/a&gt; had a great thread on twitter recently.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There’s no such thing as abstraction in web tools and never has been. Every framework claims that it will hide the complexity from you, but it always leaks through. You end up having to understand the framework, its dependencies, and the web primitives they’re built on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I first joined a software development team, I remember having my mind &lt;em&gt;blown&lt;/em&gt; as someone on the team walked me through the layers that made up the application. It was a SpringMVC web app that consisted of a view described the user interface, a model that held the data to be plugged into the view, and a controller that tied the model and view together and served requests. Hibernate was also involved in retrieving the data that populated the model. It was like staring under the hood of a car for the first time, seeing how carefully chosen components worked together to create this thing called a ‘web app’. All of those layers! Not to mentioned future joys I would experience like debugging an ORM, tuning a database, becoming fluent in the unspeakable incomprehensibilites of WebSphere, learning languages that compile into other languages, and all of the other things I’ve buried in my subconscious. Early on though it was fascinating to see those layers and exciting to think I was going to be able to contribute to the creation of an application &lt;em&gt;that someone would be using&lt;/em&gt; in real life.&lt;/p&gt;
&lt;p&gt;Now days though, when I consider all of the things someone might have to learn in order to be a productive web developer, it really is daunting. The markup languages, stylesheets, a javascript framework, a language that compiled to JS, a build tool and dependency management, all just for the client side of the application. Imagining a world where the web (good luck well-defining that btw) is as abstracted to a developer and my operating system is to me… well it seems to good to be true.&lt;/p&gt;
&lt;p&gt;The thread as some great examples and comments from others. &lt;a href=&quot;https://threadreaderapp.com/thread/1088523317089169408.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Read it unrolled&lt;/a&gt; on ThreadReader.&lt;/p&gt;</content:encoded></item><item><title>The One-Hand Approach to Production Support</title><link>https://mikebrinker.net/blog/one-hand-approach-to-production-support</link><guid isPermaLink="true">https://mikebrinker.net/blog/one-hand-approach-to-production-support</guid><description>Preserve developer focus, nurture developer autonomy</description><pubDate>Sat, 26 Jan 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Across the industry, as the teams trend away from being project-focused toward being product-focused, an increasing number of software developers find themselves being responsible for ‘support duties’. These responsibilities may include answering user questions, attempting to recreate reported bugs, and trying to recover from a system outage in production. There are reasons why it is good (this is the spirit of &lt;em&gt;DevOps&lt;/em&gt; in my opinion) that developers will increasingly participate in these duties, but for teams that are taking these responsibilities on for the first time, confusion abounds.&lt;/p&gt;
&lt;h2&gt;Assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Production incidents &lt;em&gt;will&lt;/em&gt; happen&lt;/li&gt;
&lt;li&gt;It is in the best interest of the team and product for developers to become skilled at handing production incidents&lt;/li&gt;
&lt;li&gt;We should aspire to &lt;a href=&quot;https://en.wikipedia.org/wiki/Antifragility&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Antifragility&lt;/a&gt; in our systems, our teams, and as individuals.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The All-Hands by Default Approach&lt;/h2&gt;
&lt;p&gt;To my surprise I have seen managers and developers who prefer an unorganized, all-hands approach to production support. Typically, a scenario will play out like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Production incident is reported to some sort of channel that is ‘public’ to all developers&lt;/li&gt;
&lt;li&gt;Since there is not a dedicated person to handle all issues for this given time frame, a manager type will soon be contacting developers to find out who is working on the issue.&lt;/li&gt;
&lt;li&gt;Meanwhile, a developer notices the problem and immediately notifies his/her peers&lt;/li&gt;
&lt;li&gt;Physical or virtual huddle happens and ‘all hands’ are on deck for fixing the issue&lt;/li&gt;
&lt;li&gt;Typically developers that have more experience with the system (or perhaps have more mature skill sets) lead the troubleshooting until a solution is found&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I suppose developers and managers might prefer this approach for the following reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Having a huddle creates an atmosphere or appearance of productivity and progress&lt;/li&gt;
&lt;li&gt;When all developers are in the huddle, each can suggest solutions or hypotheses that are unique to their skillset and experience (seemingly shortening the time that it takes to solve the problem)&lt;/li&gt;
&lt;li&gt;From a developer’s point of view, this approach may provide more &lt;em&gt;psychological safety&lt;/em&gt; since they aren’t the only one working on an issue&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Problems of the All-Hands Approach&lt;/h2&gt;
&lt;p&gt;There are hidden costs to the all-hands approach.&lt;/p&gt;
&lt;p&gt;First, it may seem like having a support incident channel that is public to all developers is a good idea, but I think what most managers don’t realize is the amount of distraction that channels such as these create. If a developer is told that part of their job responsibility is to monitor logged incidents, their concentration is going to be almost &lt;a href=&quot;http://calnewport.com/blog/2016/09/06/a-productivity-lesson-from-a-classic-arcade-game/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;permanently compromised&lt;/a&gt; to some degree. One extreme example I recently heard was a developer, who faced with the responsibilities of supporting an application, opened up the application logs &lt;em&gt;every morning&lt;/em&gt; and had them visible on her screen for the entire day. If something went wrong with the application, she claimed to be able to detect a change in the shape of the text that was flowing on the screen. Imagine if this person’s manager understood that this person was compromising their concentration nearly 100% of the time to visually monitor application logs!&lt;/p&gt;
&lt;p&gt;Less extreme situations still are quite a drain on a developer’s ability to focus. If you are not convinced of this I suggest taking a look at &lt;a href=&quot;http://calnewport.com/books/deep-work/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Deep Work&lt;/a&gt; by Cal Newport (decent summary &lt;a href=&quot;https://fastertomaster.com/deep-work-by-cal-newport/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;In addition to a near constant compromising of developer focus, consider the sheer &lt;em&gt;cost&lt;/em&gt; of involving everyone on the team in each production incident. As I mentioned in point number five of the &lt;em&gt;All Hands&lt;/em&gt; approach, it has often been my observation that despite all hands being present, a single developer usually ends up leading the charge at finding a solution and applying it. Given this, it is especially egregious to think that all of the members are pulled into a huddle for the incident when a subset of them will actually be contributing meaningfully to the solution.&lt;/p&gt;
&lt;h2&gt;The One-Hand (by Default) Approach&lt;/h2&gt;
&lt;p&gt;What if I could suggest an approach to handling production support that decreased distraction to the team and fostered improvement of skills and self-confidence for individual developers? That’s exactly what the &lt;em&gt;One-Hand&lt;/em&gt; approach is. It goes something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Notifications of production incidents are fed to a developer who is ‘on call’ for the given time period (let’s say they are on call for the current week). Developers who are not on call are expected to continue with their normal work.&lt;/li&gt;
&lt;li&gt;The developer works with the user (and outside teams if necessary) to resolve the issue.&lt;/li&gt;
&lt;li&gt;The on-call developer knows that as a case of last-resort, they can involve their mentor (a developer peer) or lead to get the issue resolved.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With such an approach you decrease developer distraction and increase individual problem solving skills over time.&lt;/p&gt;
&lt;p&gt;There are some cultural presuppositions that need to be installed for this to work properly. Primarily, the developer on call needs to see a production incident as an individually assigned challenge — from which they can learn and be gratified for solving. Additionally, the developer on call needs to understand that they are providing value as they protect the team from distraction, meanwhile the team as a whole needs to cherish distraction-free focus time (aka “Deep Work”) as a means to applying their unique skillsets so that they can deliver value.&lt;/p&gt;
&lt;p&gt;Finally, the decision to bring another developer into a huddle needs to be understood as something undesirable but potentially necessary in a given instance. The developer on-call should set out thinking of pulling someone else in as a last resort, but the rest of the team should not think of this as an &lt;em&gt;ostrasizable&lt;/em&gt; offense. If the team is mature enough to work under these assumptions, the One-Hand approach yields the following benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Protects the majority of the team from distraction&lt;/li&gt;
&lt;li&gt;Removes the latent stress of the entire team watching a public channel, waiting for something bad to happen&lt;/li&gt;
&lt;li&gt;Forces all team members to ‘level up’ the various skills needed for production support&lt;/li&gt;
&lt;li&gt;Each developer who handles an incident will have increased confidence and know-how&lt;/li&gt;
&lt;li&gt;Over time you decrease the amount of single-person dependencies the team has&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This approach goes hand-in-hand with the idea of Antifragility. A team needs to be strengthened by various stressors in its environment. A system needs ‘adaptive fault tolerance’ (See the &lt;a href=&quot;https://www.sciencedirect.com/science/article/pii/S1877050916302290&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Antifragile Software Manifesto&lt;/a&gt;). An individual needs to be tested and strengthened to a degree in order to become better (interestingly, Jonathan Haidt even &lt;a href=&quot;https://www.youtube.com/watch?v=tvb7R6GF6CU&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;applies Antifragility&lt;/a&gt; to childhood development).&lt;/p&gt;
&lt;h2&gt;In Sum&lt;/h2&gt;
&lt;p&gt;Yes, there might be some situations where the All-Hands approach is needed. If these instances are not rare on your team, something else is probably gravely wrong.&lt;/p&gt;
&lt;p&gt;Yes, the lead of the team or mentor will still be generally distracted as junior developers come to them with production incidents. This is the sad, lonely road  walked by the developer who chooses to mentor or take the lead on a team.&lt;/p&gt;
&lt;p&gt;Ultimately, the One-hand (by default) approach ends up delivering a more focused and capable team and a generally saner work environment.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Do you violently disagree me? Do you have a legendary story from that night you were on-call? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>IDEs are dead. Long Live Development Environments. (Part 2)</title><link>https://mikebrinker.net/blog/benefits-of-stepping-away-from-your-ide</link><guid isPermaLink="true">https://mikebrinker.net/blog/benefits-of-stepping-away-from-your-ide</guid><description>The benefits of stepping away from your IDE.</description><pubDate>Sat, 12 Jan 2019 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you haven’t yet, you may want to refer to &lt;a href=&quot;https://mikebrinker.net/blog/step-away-from-your-ide/&quot;&gt;part 1 of this series&lt;/a&gt; where I present a reasoned argument against using an IDE. Now let me try to explain why it was so beneficial for me.&lt;/p&gt;
&lt;p&gt;I attribute major positive impacts to my professional competency as a developer to pulling away from my IDE and creating a development environment for myself. Below, I attempt categorize the positive impacts into 4 major groups.&lt;/p&gt;
&lt;h3&gt;1. Increased competency with individual tools&lt;/h3&gt;
&lt;p&gt;I first noticed that by using some tools directly, I began to understand them better than I did when I was using them through the abstraction of my IDE. Interacting with a tool on its terms (the interface that it provides) forces you to learn the concepts inherent with the tool rather than the way they have been abstracted away by your IDE.&lt;/p&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Git&lt;/strong&gt;. Git’s CLI is well known as being confusing and inconsistent. Many choose to use Git through their IDE of with applications like Tig, SourceTree, Kraken, etc… While these tools can be beneficial in specific use cases (I find no shame in relying on SourceTree or BitBucket for complicated diffs) they generally obfuscate the underlying concepts of Git. Learning to use Git’s CLI has allowed me to extract more value from this notoriously complicated tool.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependency Management&lt;/strong&gt; (NPM, Yarn, Bundler, Gradle) Using the command line interface for these tools rather than the menus in an IDE forced me to better understand the role that they play in the software development lifecycle. When I was a pure IDE user, I knew that in some cases I had to run a &lt;em&gt;gradle refresh&lt;/em&gt; or &lt;em&gt;gradle build&lt;/em&gt; but these were actually more like debugging steps when something went wrong in my local environment. After learning the tools individually and directly I better understood when I needed to use them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Improved debugging skills&lt;/h3&gt;
&lt;p&gt;I next noticed that when a production issue arose I had become much more comfortable with jumping on servers and getting to the bottom of an issue. When I was purely an IDE user, the thought of understanding how an application was running on in our target environment seemed much more foreign than the comfort of my Eclipse’s GUI. Working primarily in a terminal and interacting with tools via their CLI led me to be much more comfortable with ops-related tasks. It also helped me come to understand the OS I was using more thoroughly.&lt;/p&gt;
&lt;h3&gt;3. Becoming a technical resource&lt;/h3&gt;
&lt;p&gt;After I noticed my increased ability with individual tools and improved debugging skills in my day to day software development activities, a third interesting benefit began to manifest — people began to come to me when they had problems with an individial tool. This may seem like an obvious progression as you read this blog post, but as it was happening to me, I was not planning to become ‘the Git guy’ when I started using Git directly via its CLI but nonetheless from time to time coworkers would come to me with a problem and much to my surprise I was often able to help them.&lt;/p&gt;
&lt;h3&gt;4. Adaptability&lt;/h3&gt;
&lt;p&gt;Finally, I noticed that when I switched development stacks, I was able to adapt easily to a new set of tools. Once I became somewhat ‘intimate’ with the tools in the first stack that I learned (Java based webapps) I then moved to a fullstack Javascript environment. I was a little nervous moving from Java to fullstack JS, but I found myself asking diagnostic questions based on tooling to get me through it. Rather than making a list of all the new tools I needed to learn to be a successful fullstack Javascript developer (and then researching them one by one), I was able to use the mental models I had of the tooling in my previous stack to gradually come to understand the new one. I would speak to myself like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Alright, I need to pull down the dependencies for my project. In the past I used Gradle for that. What do I have now? NPM. Great. Let’s see what the equivalent of &lt;code&gt;gradle build&lt;/code&gt; is for NPM.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;In Sum&lt;/h2&gt;
&lt;p&gt;In the end I was often pleasantly surprised to find that from stack to stack, smart people have developed tools that share similar roles and very often these tools even use similar terminology. (Moving from Yarn to Bundler for example required very little research)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;So, are you sold on the benefits of ditching your IDE yet? Read my &lt;a href=&quot;https://mikebrinker.net/blog/build-a-development-environment/&quot;&gt;step-by-step guide to getting rid of your IDE&lt;/a&gt;. Otherwise, let me know in the comments if you have found similar benefits.&lt;/p&gt;</content:encoded></item><item><title>IDEs are dead. Long Live Development Environments. (Part 1)</title><link>https://mikebrinker.net/blog/step-away-from-your-ide</link><guid isPermaLink="true">https://mikebrinker.net/blog/step-away-from-your-ide</guid><description>Why you should step away from your IDE.</description><pubDate>Sat, 05 Jan 2019 16:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;Generally, I don’t think there are one-size-fits-all solutions in software development and engineering. I’m going to argue that it will be good for you to step away from your IDE because it was good for me to do so. If you totally disagree with me, that’s cool! Tell me your experience in the comments section.&lt;/p&gt;
&lt;h2&gt;The Sacrifice You Didn’t Know You Were Making&lt;/h2&gt;
&lt;p&gt;When it comes to being productive as a software developer there are many categories of personality that manifest regarding productivity. I speak from experience here, I’ve dabbled in nearly all of these. There are coffee addicts, nootropic pill-poppers, noise-cancelling headphone donners, binaural beat dweebs, flow-state seekers, text-editor worshippers, point-and-click mouse nuts, keyboard-only wingdings, the list goes on. I would like to take this moment to introduce what I consider a dangerous software developer personality, &lt;em&gt;the IDE indentured servant&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The IDE indentured servant is the person who relies on their trusty IDE as a prized productivity tool but doesn’t realize that it’s actually holding them back. Whatever gains they may have gotten in short-term productivity (which I believe is a &lt;em&gt;false&lt;/em&gt; productivity), they completely sacrifice when it comes to long-term productivity.&lt;/p&gt;
&lt;p&gt;I’m here to tell you today that &lt;em&gt;IDEs are a drain on your productivity&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use an IDE if you want to stunt your software developer development.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use an IDE if you want to be a &lt;em&gt;lesser&lt;/em&gt; developer.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Do I have your attention? Cool.&lt;/p&gt;
&lt;p&gt;Let’s go back to productivity for a second. Everyone knows a developer who’s measure of productivity is getting a feature deployed to a test environment so that they can start the next feature. These are the people who feel good about getting something ‘done’. These are also the people who usually forget to finish things in my experience. I have trouble with this myself actually. The gratification I get from ‘finishing’ something can lead me to prematurely move onto something else if I’m not careful. Let’s call this &lt;em&gt;short term productivity&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Conversely we have &lt;em&gt;long term productivity&lt;/em&gt;; finishing things that provide value and getting them right.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Slow is smooth and smooth is fast.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Measure twice and cut once.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is truth to these aphorisms! (not least because Phil Dunphy champions the former). It’s the developer who desires long term productivity that needs to ditch her IDE.&lt;/p&gt;
&lt;h2&gt;Why the IDE hate?&lt;/h2&gt;
&lt;p&gt;Think about what an IDE actually does. The most charitable description would be that it ties together many tools and utilizes them to give instant feedback to the developer. This actually might be true, but there is one terrible side effect that most don’t consider: IDEs abstract the developer away from the very tools that they are using. This abstraction generates a distance between the developer and their tools. This distance may be helpful in the short term (imagine training wheels on a bike) but will only hurt in the long term (try riding your bike off road being dependent on training wheels).&lt;/p&gt;
&lt;p&gt;Don’t believe me?&lt;/p&gt;
&lt;p&gt;Consider this for a moment: &lt;em&gt;becoming competently productive with a particular IDE is orthogonal to being competently productive in a given language technology stack&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Learning how to use an IDE doesn’t actually teach you how to use the underlying tools that it ‘integrates’. Please join me in a short though experiment.&lt;/p&gt;
&lt;h3&gt;The Junior Developer + Git&lt;/h3&gt;
&lt;p&gt;Take version control for example. Imagine a junior developer who joins a team and begins their first project, which happens to be written in Ruby. For the sake of the experiment, imagine that they know nothing about Git. They reach for the RubyMine IDE from JetBrains. RubyMine has a fair amount of VCS tooling off the shelf that helps you do things with Git. There is some overlap between the terminology used by RubyMine’s VCS features and the Git CLI, but it’s not 100%.&lt;/p&gt;
&lt;p&gt;So the junior dev works on this project for 6 months.  They’ve been using the RubyMine VCS tools to commit and push their changes. At the end of 6 months, how much have they learned about Git?&lt;/p&gt;
&lt;p&gt;I think we all know the answer. They have learned &lt;em&gt;very little&lt;/em&gt; about Git. They have probably memorized the menu items or keyboard shortcuts that are needed to commit and push to a branch, but they probably aren’t aware of the differences between the Git index, staged files, and committed files for example.&lt;/p&gt;
&lt;p&gt;I’m not saying it’s logically necessary for a developer to know the internals of Git to be successful. Being a software developer is about providing value to the people that we are making the software for. You don’t have to be a Git ninja to provide value. However, There will be a point though when the developer who doesn’t know Git very well will likely lose some of their work, blow away a remote branch accidentally, or get very confused when someone asks them to “Cherry pick” a commit. In this moment who is the person that every one turns to? It’s the guy who always uses the Git CLI.&lt;/p&gt;
&lt;h3&gt;Some Personal Experience&lt;/h3&gt;
&lt;p&gt;My first project was in Java and we used CVS (shudder) for version control. I used the CVS tooling built into Eclipse every time I pushed, pulled, compared, etc… just like the rest of my team. There was one time where something went horribly wrong with the CVS repo on our CVS server. You know who my team needed help from to get it fixed? The token Emacs user that sat near us. He had been using the CVS CLI all along. He made quick work of the problem that we had. It was trivial enough for him to fix  that none of us ever understood what the problem was.&lt;/p&gt;
&lt;p&gt;I humbly suggest that this will happen not only with VCS tools but dependency management tools, interpreters, compilers, application servers, linters, code coverage tools, and build tooling.&lt;/p&gt;
&lt;h2&gt;In Sum&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;In order to integrate developer tools into a single environment, IDEs abstract tooling away which has the unfortunate side effect of obscuring the developer from their tooling&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It is my contention that this may be good for short-term productivity, but is almost certainly bad for long-term productivity.&lt;/p&gt;
&lt;p&gt;Take a look at &lt;a href=&quot;https://mikebrinker.net/blog/benefits-of-stepping-away-from-your-ide/&quot;&gt;part 2 of this series&lt;/a&gt; to understand why stepping way from an IDE was so beneficial to me.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Do you completely disagree with me? Excellent! Please let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>How does DNS work?</title><link>https://mikebrinker.net/blog/how-does-dns-work</link><guid isPermaLink="true">https://mikebrinker.net/blog/how-does-dns-work</guid><description>A primer for software developers who want to know more.</description><pubDate>Thu, 27 Dec 2018 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Whether you realize it or not, DNS is a workhorse of the internet ecosystem. It provides the glue that allows someone like your grandma, (who knows that you want a pair of Adidas Ultraboost from footlocker.com for Christmas) to talk TCP with a server on the other side of the world.&lt;/p&gt;
&lt;p&gt;It’s amazing when you think about it…&lt;/p&gt;
&lt;p&gt;Your grandma really is quite kind.&lt;/p&gt;
&lt;p&gt;So, let’s start from first principles and dig in to understand DNS a bit more.&lt;/p&gt;
&lt;h2&gt;What exactly is DNS?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;DNS, or the &lt;em&gt;Domain Name System&lt;/em&gt; is an abstraction layer that maps the human-readable web addresses that we know and love to IP addresses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For a long time, that was about the extent of my knowledge of DNS. I knew that there were servers out in the ether of the internet that contained those mappings.  Later on, I learned that one could use &lt;code&gt;nslookup&lt;/code&gt; to find existing mappings. Beyond that, I knew very little. The majority of the time this was enough, but every now and then I would hear someone mention an &lt;code&gt;A&lt;/code&gt; record or a &lt;code&gt;CNAME&lt;/code&gt; record and I couldn’t contribute much to the conversation other than “Ah yes, that has something to do with DNS”.  If you are like me, the things that you know that you don’t know serve as bread crumbs for the things that you want to learn.  Let’s follow those breadcrumbs a bit.&lt;/p&gt;
&lt;h2&gt;The lifecycle of a DNS query&lt;/h2&gt;
&lt;p&gt;Interview questions like “Tell me everything that happens when I navigate to google.com” are quite fun to answer for me.  This is mainly because there are endless ways to tell the story of all the things that go on when a user does x.  At some point though, we have to limit the detail of our explanations in order to actually provide value. Be forewarned: the explanatory lifecycle of a DNS query below is not exhaustive! Exhaustive references can be useful but not so much in didactic contexts.&lt;/p&gt;
&lt;p&gt;So what happens when a domain name query is issued to DNS?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Someone named Jeffrey asks their computer to go to google.com&lt;/li&gt;
&lt;li&gt;The operating system of Jeffrey’s computer consults its own cache to see if the IP address for the requested name is already known. If it is, life is good! If not…&lt;/li&gt;
&lt;li&gt;Jeffrey’s operating system reaches out to a DNS cacher/recursor which we will refer to as the &lt;em&gt;local DNS server&lt;/em&gt; from here onward. The local DNS server is very often provided by your ISP, but sufficiently advanced LANs will often have their own local DNS server.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;local DNS server&lt;/em&gt; will check its cache. If it has an answer to the query, life is good! If not…&lt;/li&gt;
&lt;li&gt;The local DNS server will recursively contact other DNS servers until it can provide an authoritative answer.  The recursive DNS request looks something like:
&lt;ul&gt;
&lt;li&gt;Local DNS server asks a root DNS server where to find the .com TLD (top level domain) server. The root DNS server provides the answer.&lt;/li&gt;
&lt;li&gt;Local DNS server then asks the .com TLD DNS server for the “google” name server. The .com TLD DNS server provides the answer.&lt;/li&gt;
&lt;li&gt;Local DNS server asks the “google” DNS server for the google.com IP. The “google” name server provides an answer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The local DNS server returns the IP address provided by the “google” name server to Jeffrey’s computer. (and hopefully caches the answer!)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;What is a DNS record?&lt;/h2&gt;
&lt;p&gt;The response provided by a DNS server represents a &lt;em&gt;record&lt;/em&gt; that exists in the Domain Name System. One might find that the responses representing records are referred to as a &lt;em&gt;record&lt;/em&gt; themselves. YMMV.&lt;/p&gt;
&lt;p&gt;Below I explain a few of the common DNS record types. There are many more. For more details you may want to consult this &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_DNS_record_types&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;helpful and complete list&lt;/a&gt; of DNS record types.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;CNAME&lt;/code&gt; Records&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;CNAME&lt;/code&gt; record is said to be “the canonical name for an alias” in &lt;a href=&quot;https://tools.ietf.org/html/rfc1035&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RFC 1035&lt;/a&gt;.  &lt;code&gt;CNAME&lt;/code&gt; records map an alias to another name. Upon receiving a &lt;code&gt;CNAME&lt;/code&gt; response, the  computer issuing a DNS query will restart the query using the value that the &lt;code&gt;CNAME&lt;/code&gt; record points too. Note: While DNS is actually resolving the IP of the canonical name, the original name request (the alias) is what users will see in their browser.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CNAME&lt;/code&gt; records are intended to point to a canonical name, but there is nothing that prevents one from creating a CNAME record that point to another alias. One could even create an infinite loop if they so desired.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;DNAME&lt;/code&gt; Records&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;DNAME&lt;/code&gt; record “provides redirection for a subtree of the domain” accord to its RFC (&lt;a href=&quot;https://tools.ietf.org/html/rfc6672&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RFC 6672&lt;/a&gt;). For this reason is it known as a &lt;em&gt;delegation&lt;/em&gt; record.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;A&lt;/code&gt;  Records&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;A&lt;/code&gt; records are described as providing “a host address” in &lt;a href=&quot;https://tools.ietf.org/html/rfc1035&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RFC 1035&lt;/a&gt;. &lt;code&gt;A&lt;/code&gt; records are the meat and potatoes(?) of DNS. The provide a simple mapping from a name to an IP address.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Did I get something wrong? Is there another subset of DNS functionality that needs to be explained? Let me know in the comments.&lt;/p&gt;</content:encoded></item><item><title>The Bad Plus</title><link>https://mikebrinker.net/blog/bad-plus</link><guid isPermaLink="true">https://mikebrinker.net/blog/bad-plus</guid><description>A jazz trio you might be able to love even if you hate jazz</description><pubDate>Sat, 08 Dec 2018 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve found over the years that there is some music that is well-suited for listening while doing software-development related work and some music is not. Rather than try to derive a special formula for “coding music” I’m going to tell you about some music that works for me. One group I’ve been listening to for awhile that works particularly well is &lt;em&gt;The Bad Plus&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Bad Plus&lt;/em&gt; is a jazz piano trio that might not sound like a jazz group to you at first blush. They employ jazz idioms and instrumentation on popular cover tunes and their own originals as well. I find a wide range of mood and tone in their music: calm and nearly ambient, cacophonic excitement, and even straight ahead tunes with lots of energy. Despite the diversity it all works nicely when I’m clacking away on the keyboard.&lt;/p&gt;
&lt;p&gt;I highly recommend catching them live if they are ever playing in your town. The occasions I’m which I had the priviledge of hearing The Bad Plus did not disappoint – YouTube has a nice selection of live recordings available. One can only hope they release more live music in the future.&lt;/p&gt;
&lt;h2&gt;Song Selection for Work&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Anthem for the Earnest&lt;/li&gt;
&lt;li&gt;Flim&lt;/li&gt;
&lt;li&gt;As the Moment Slips Away&lt;/li&gt;
&lt;li&gt;Beauty Has It Hard&lt;/li&gt;
&lt;li&gt;We are the Champions&lt;/li&gt;
&lt;li&gt;Forces&lt;/li&gt;
&lt;li&gt;Prehensile Dream&lt;/li&gt;
&lt;li&gt;Silence is the Question&lt;/li&gt;
&lt;li&gt;1983 Regional All-Star&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cQNybpWVS3o&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Newport Jazz Festival, 2006&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=11YQwpNM1ng&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Moers Festival, 2017&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>The Serverless Sea Change</title><link>https://mikebrinker.net/blog/the-serverless-sea-change</link><guid isPermaLink="true">https://mikebrinker.net/blog/the-serverless-sea-change</guid><description>Serverless architecture might have a shot</description><pubDate>Fri, 07 Dec 2018 16:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I read a great article at InfoQ this week called &lt;a href=&quot;https://www.infoq.com/articles/serverless-sea-change&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;The Serverless Sea Change&lt;/em&gt;&lt;/a&gt;. Generally, the argument made is that code leads to technical debt, therefore the solution with the least amount of code wins. For example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you are building a Serviceful Serverless application, you will need to spend significantly more time on research than you would with an application where you will write everything. This is because you will be implementing much more functionality of the application on services, and you need to verify that you are selecting the correct service. You also need to figure out the right way to integrate the service with your application. So instead of spending an hour or two looking for packages you might leverage, you should think about spending days and even weeks writing proof-of-concept code and testing different options.&lt;/p&gt;
&lt;p&gt;Another way to say this is in two equations:&lt;/p&gt;
&lt;p&gt;2 Weeks Research + 1 Day Development → N Lines of Code to Maintain&lt;/p&gt;
&lt;p&gt;1 Day Research + 2 Weeks Development → 10 ⋅ N Lines of Code to Maintain&lt;/p&gt;
&lt;p&gt;On average, ten times more lines of code is ten times more technical debt, which means increasingly slower and less predictable future development velocity, and systems that cannot be well maintained by the average developer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’ve generally remained skeptical as to whether the advantages of serverless architectures outweigh the benefits, or to put it another way, if there are any advantages when all is sasaid and done. For me, the looming issues are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vendor Lock-in&lt;/li&gt;
&lt;li&gt;Conversely, the portability of any artifact targeting a FaaS platform&lt;/li&gt;
&lt;li&gt;The amount of glue needed to make serverless work (any AWS Lambda demo I’ve seen spends more time gluing AWS services together than it does writing code)&lt;/li&gt;
&lt;li&gt;In the case of AWS, many of the glue services are still beta products&lt;/li&gt;
&lt;li&gt;Ease of local development&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;Cold Starts&lt;/em&gt; problem&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I remain skeptical, but this article does a great job of explaining and arguing for the benefits. Also, perhaps I am wrong (!) and we are a few years away from a true “Serverless Sea Change”.&lt;/p&gt;
&lt;p&gt;Be sure to check out the whole article over at &lt;a href=&quot;https://www.infoq.com/articles/serverless-sea-change&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;InfoQ&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>