<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://jfjrh2014.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jfjrh2014.github.io/" rel="alternate" type="text/html" /><updated>2026-06-12T20:04:56+00:00</updated><id>https://jfjrh2014.github.io/feed.xml</id><title type="html">Marcus Harrison</title><subtitle>Code, comedy, and questionable puns. A developer&apos;s corner of the internet.</subtitle><author><name>Marcus Harrison</name></author><entry><title type="html">Your Function Has Too Many Arguments (And Other Uncomfortable Truths)</title><link href="https://jfjrh2014.github.io/go/2026/06/12/too-many-arguments.html" rel="alternate" type="text/html" title="Your Function Has Too Many Arguments (And Other Uncomfortable Truths)" /><published>2026-06-12T20:00:00+00:00</published><updated>2026-06-12T20:00:00+00:00</updated><id>https://jfjrh2014.github.io/go/2026/06/12/too-many-arguments</id><content type="html" xml:base="https://jfjrh2014.github.io/go/2026/06/12/too-many-arguments.html"><![CDATA[<p>It’s honesty time. We’ve all written a function that takes seven arguments and convinced ourselves it’s fine. “It’s not <em>that</em> many,” we whisper, adding an eighth one just to handle that one edge case.</p>

<p>Let me be direct: your function has too many arguments.</p>

<h2 id="the-magic-number-is-low">The Magic Number Is… Low</h2>

<p>Go doesn’t have named parameters or default values. Every argument is positional, every call site is a miniature archaeological dig. When you see:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ProcessOrder</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">items</span><span class="p">,</span> <span class="no">true</span><span class="p">,</span> <span class="no">false</span><span class="p">,</span> <span class="no">true</span><span class="p">,</span> <span class="no">nil</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="m">0</span><span class="p">)</span>
</code></pre></div></div>

<p>you are no longer programming. You are gambling. What’s the third <code class="language-plaintext highlighter-rouge">true</code>? Nobody knows. Not even you, and you wrote it yesterday.</p>

<p>Option structs are the cure:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="n">OrderOptions</span> <span class="k">struct</span> <span class="p">{</span>
    <span class="n">Validate</span>   <span class="kt">bool</span>
    <span class="n">Notify</span>     <span class="kt">bool</span>
    <span class="n">Priority</span>   <span class="kt">int</span>
    <span class="n">CouponCode</span> <span class="kt">string</span>
<span class="p">}</span>

<span class="n">ProcessOrder</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">items</span><span class="p">,</span> <span class="n">OrderOptions</span><span class="p">{</span>
    <span class="n">Validate</span><span class="o">:</span> <span class="no">true</span><span class="p">,</span>
    <span class="n">Notify</span><span class="o">:</span>   <span class="no">true</span><span class="p">,</span>
<span class="p">})</span>
</code></pre></div></div>

<p>Every caller is now self-documenting. Unused fields stay zero-valued. Future-you stops guessing.</p>

<h2 id="but-wait-theres-more">But Wait, There’s More</h2>

<p>This isn’t just about readability. Functions with many parameters are usually doing too many things. If you need eight inputs, your function has at least three responsibilities fighting for control of the return value.</p>

<p>Split it. Compose it. Let each piece do one thing well.</p>

<p>A function with two arguments and one responsibility will outlive your entire codebase. A function with nine arguments will outlive your will to maintain it.</p>

<h2 id="the-real-danger">The Real Danger</h2>

<p>The worst part isn’t the pain of writing these functions. It’s that they <em>work</em>. They compile. They pass tests. They ship. And then six months later someone adds a tenth parameter, mistypes the seventh boolean, and production goes down at 2 AM on a Sunday.</p>

<p>That person will be you. It’s always you.</p>

<h2 id="a-simple-rule-of-thumb">A Simple Rule of Thumb</h2>

<p>If your function takes more than three arguments, stop and ask yourself:</p>

<ol>
  <li>Should some of these be a struct?</li>
  <li>Should this be two functions instead of one?</li>
  <li>Would Past Marcus thank me for simplifying this?</li>
</ol>

<p>If the answer to any of those is yes, refactor now. Your future self is already stressed enough without decoding boolean sandwiches at dawn.</p>

<p>The best code isn’t clever. It’s obvious. And nothing says “obvious” like a function that takes exactly what it needs and nothing more.</p>

<p>Now go check your codebase. I’ll wait. It’s fine. I’m not judging.</p>

<p>…Okay, I’m judging a little.</p>]]></content><author><name>Marcus H.</name></author><category term="go" /><summary type="html"><![CDATA[It’s honesty time. We’ve all written a function that takes seven arguments and convinced ourselves it’s fine. “It’s not that many,” we whisper, adding an eighth one just to handle that one edge case.]]></summary></entry><entry><title type="html">The Five Stages of Grieving a nil Pointer</title><link href="https://jfjrh2014.github.io/go/2026/06/05/nil-pointer-grief.html" rel="alternate" type="text/html" title="The Five Stages of Grieving a nil Pointer" /><published>2026-06-05T00:00:00+00:00</published><updated>2026-06-05T00:00:00+00:00</updated><id>https://jfjrh2014.github.io/go/2026/06/05/nil-pointer-grief</id><content type="html" xml:base="https://jfjrh2014.github.io/go/2026/06/05/nil-pointer-grief.html"><![CDATA[<p>Every Go developer knows the feeling. Your service has been humming along in production for weeks. You deploy a tiny refactor — barely a diff, more of a gentle suggestion — and at 3:47 AM your pager coughs to life with the most feared three words in the language: <strong>nil pointer dereference</strong>.</p>

<p>What follows is grief. Pure, structured, Kübler-Ross-approved grief.</p>

<h2 id="1-denial">1. Denial</h2>

<p>“This can’t be nil. I just initialized it on the line above. The tests passed. The linter was happy. My rubber duck nodded solemnly.”</p>

<p>You reread the function. You reread it again. You add a <code class="language-plaintext highlighter-rouge">fmt.Println</code> like a fingerprints-on-the-window detective. It is, of course, nil. The variable was initialized in a different scope, or returned early from a branch you forgot existed, or quietly shadowed by a loop variable three callbacks deep.</p>

<p><strong>Symptom:</strong> Adding <code class="language-plaintext highlighter-rouge">if x == nil { return }</code> defensively and pretending this is “defensive programming.”</p>

<h2 id="2-anger">2. Anger</h2>

<p>“Why doesn’t this language have optional types? Why is <code class="language-plaintext highlighter-rouge">nil</code> even a thing? Rust doesn’t have this problem. My grandma doesn’t have this problem. She doesn’t write Go, but still.”</p>

<p>This is the stage where you tweet things like <em>“Go’s error handling is fine actually, it’s <code class="language-plaintext highlighter-rouge">nil</code> that’s the crime.”</em> You consider filing a proposal. You read three old Go issue threads from 2017. You close them feeling worse.</p>

<p><strong>Symptom:</strong> Strong opinions on <code class="language-plaintext highlighter-rouge">errors.Join</code> and a half-written blog post titled “We Deserve Better.”</p>

<h2 id="3-bargaining">3. Bargaining</h2>

<p>“Okay, what if I wrap everything in a struct? What if I add a <code class="language-plaintext highlighter-rouge">Valid() bool</code> method? What if I use <code class="language-plaintext highlighter-rouge">*T</code> only when I really, really mean it? What if I just sprinkle <code class="language-plaintext highlighter-rouge">if err != nil</code> a little harder?”</p>

<p>You discover <code class="language-plaintext highlighter-rouge">google/go-cmp</code> and convince yourself that better tooling will save you. It will not. But you write the comparison anyway, and for one holy moment the test passes.</p>

<p><strong>Symptom:</strong> Your struct now has four helper methods named <code class="language-plaintext highlighter-rouge">IsZero</code>, <code class="language-plaintext highlighter-rouge">IsValid</code>, <code class="language-plaintext highlighter-rouge">NotNil</code>, and <code class="language-plaintext highlighter-rouge">Dave</code> (Dave is for luck).</p>

<h2 id="4-depression">4. Depression</h2>

<p>You look at your call stack. The nil escaped from a goroutine that called a closure that read from a channel that was populated by a JSON unmarshaler that didn’t know your field existed. The nil is thirteen frames above you. You are at its mercy.</p>

<p>You open the Go FAQ. It does not help. You open the spec. It does help, but in the way a doctor’s diagnosis helps: you now have a name for the thing that’s hurting you.</p>

<p><strong>Symptom:</strong> The <code class="language-plaintext highlighter-rouge">// TODO: fix this</code> comment from 2024 suddenly makes sense.</p>

<h2 id="5-acceptance">5. Acceptance</h2>

<p>You write the nil check. You write a test that constructs the nil on purpose. You add a comment explaining why the nil can happen, who is responsible for it, and what the caller should do. You begin to see nil not as a bug, but as a feature — a small, polite “no comment” from the runtime about a value that simply isn’t there.</p>

<p>You ship. You sleep. The pager stays quiet.</p>

<p><strong>Symptom:</strong> You start sentences with “So actually, <code class="language-plaintext highlighter-rouge">nil</code> is kind of elegant if you think about it…” at parties. People stop inviting you to parties.</p>

<h2 id="the-real-lesson">The Real Lesson</h2>

<p>The five stages aren’t really about <code class="language-plaintext highlighter-rouge">nil</code>. They’re about every sharp edge in Go: channels that block forever, maps that race, goroutines that leak, <code class="language-plaintext highlighter-rouge">interface{}</code> that pretends to be a type. The language is small on purpose, and small languages hand you the loaded gun.</p>

<p>That’s also why I love it. There’s no macro to hide behind, no decorator to wave at the bad smell. When something is wrong in Go, it is <em>visibly, desperately wrong</em>, in your face, on line 47, with a stack trace that points right at the crime scene.</p>

<p>The fix is almost always the same: a small function, a clear comment, a test that doesn’t apologize. Go doesn’t reward cleverness. It rewards kindness to your future self.</p>

<p>So the next time the pager goes off at 3:47 AM, take a breath, open the file, look at the nil, and remember: you are not the first developer to grieve, and you will not be the last. Kübler-Ross just forgot to include <code class="language-plaintext highlighter-rouge">panic: runtime error: invalid memory address</code> as a footnote.</p>

<p>Stay typed, friends.</p>

<p>— Marcus H.</p>]]></content><author><name>Marcus Harrison</name></author><category term="go" /><summary type="html"><![CDATA[Every Go developer knows the feeling. Your service has been humming along in production for weeks. You deploy a tiny refactor — barely a diff, more of a gentle suggestion — and at 3:47 AM your pager coughs to life with the most feared three words in the language: nil pointer dereference.]]></summary></entry><entry><title type="html">Hello, World. Or: How I Learned to Stop Worrying and Love the Stack Trace</title><link href="https://jfjrh2014.github.io/personal/2026/06/04/hello-world.html" rel="alternate" type="text/html" title="Hello, World. Or: How I Learned to Stop Worrying and Love the Stack Trace" /><published>2026-06-04T00:00:00+00:00</published><updated>2026-06-04T00:00:00+00:00</updated><id>https://jfjrh2014.github.io/personal/2026/06/04/hello-world</id><content type="html" xml:base="https://jfjrh2014.github.io/personal/2026/06/04/hello-world.html"><![CDATA[<p>Hi. I’m Marcus. I write code for a living and jokes for… well, also for a living, if you count team morale as a deliverable.</p>

<p>I’m a developer currently living in Helsinki, originally from Birmingham. Yes, I traded grey skies for… different grey skies. But the coffee here is phenomenal, and the saunas fix what the weather breaks.</p>

<p>This blog is my little corner of the internet. A place to dump thoughts about software, things I’ve learned contributing to open source, and probably too many puns about arrays (I’d make a joke about recursion, but you’d just hear it again).</p>

<p>I spend my days writing Go and JavaScript, my evenings doing stand-up comedy, and somewhere in between I manage to sleep. usually.</p>

<p>If you’re reading this, you either know me, got lost on GitHub, or Google’s algorithm has a sense of humor. Either way, welcome.</p>

<p>Let’s debug this with a smile.</p>

<p>— Marcus</p>]]></content><author><name>Marcus Harrison</name></author><category term="personal" /><summary type="html"><![CDATA[Hi. I’m Marcus. I write code for a living and jokes for… well, also for a living, if you count team morale as a deliverable.]]></summary></entry></feed>