<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://www.yellowduck.be/pretty-atom-feed-v3.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <link href="https://www.yellowduck.be" rel="alternate"/>
  <link href="https://www.yellowduck.be/posts/feed" rel="self"/>
  <author>
    <name>Pieter Claerhout</name>
    <email>pieter@yellowduck.be</email>
  </author>
  <id>https://www.yellowduck.be/posts/feed</id>
  <title>🐥 YellowDuck.be</title>
  <updated>2026-06-26T17:00:00Z</updated>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-stack-behind-there-there" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;What does a modern support application look like? In a revealing piece, Freek shares the technical stack underpinning the beta version of There There, a Laravel app developed by Spatie. Utilizing a mix of proven frameworks and tools, they prioritize stability and maintainability over the latest trends. The choice of Laravel, combined with AI capabilities and a structured code organization by domain, allows for efficient service delivery.&lt;/p&gt;
&lt;p&gt;The integration of Inertia and React offers a seamless user experience, while Laravel&apos;s ecosystem enriches functionality through custom packages. The article outlines not just the elegant configuration but also the mundane yet crucial infrastructure that supports smooth operations. This stack not only enhances productivity but also ensures reliability in managing customer interactions, bridging the gap between technology and user satisfaction.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://there-there.app/blog/the-stack-behind-there-there&quot;&gt;Continue reading on &lt;strong&gt;there-there.app&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/frontend&quot;&gt;#frontend&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-26T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-stack-behind-there-there</id>
    <title>🔗 The stack behind There There</title>
    <updated>2026-06-26T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/routeparameter-does-not-bind-your-model" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;If &lt;code&gt;#[RouteParameter]&lt;/code&gt; in your Laravel form request receives a string instead of a model, it&apos;s often not about failed binding but about the absence of binding altogether. Laravel&apos;s &lt;code&gt;#[RouteParameter]&lt;/code&gt; attribute enhances type safety but only reads the current route parameter value. It does not perform route model binding, which means if the controller doesn&apos;t provide enough information for implicit binding, the form request might get the raw route string instead of an &lt;code&gt;Event&lt;/code&gt; model.&lt;/p&gt;
&lt;p&gt;This article dives into the nuances of using &lt;code&gt;#[RouteParameter]&lt;/code&gt; in form requests and highlights why it&apos;s crucial to keep the model in both the controller method signature and the form request constructor. It articulates a vital point: Laravel relies on the controller&apos;s method signature to perform implicit route model binding. Without it, the model won&apos;t be resolved correctly, potentially leading to errors. Understanding this can save developers from common pitfalls in Laravel&apos;s routing and request handling.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://dyrynda.com.au/blog/route-parameters-can-hurt&quot;&gt;Continue reading on &lt;strong&gt;dyrynda.com.au&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/php&quot;&gt;#php&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-26T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/routeparameter-does-not-bind-your-model</id>
    <title>🔗 #[RouteParameter] does not bind your model</title>
    <updated>2026-06-26T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/why-enterprise-ai-projects-fail-5-root-causes-fixes" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Enterprise AI failure is rarely a modeling problem. Instead, projects stall due to organizational structures that don’t support deployment. A proof-of-concept may clear its demo, but then the initiative can languish for months, with no single role accountable for moving forward. For CTOs and Heads of AI in mid-to-large enterprises, this structural issue is pervasive, as highlighted in the analysis of five key failure modes that hinder AI initiatives from reaching production.&lt;/p&gt;
&lt;p&gt;According to industry research, 90% of corporate AI initiatives struggle beyond test stages, often due to organizational priorities favoring technology over strategy, rather than issues with the model itself. The article delves into these failure modes, offering actionable fixes to ensure that AI projects transition smoothly from pilots to production-ready systems. By addressing common pitfalls like pilot purgatory and lack of ownership, organizations can enhance their chances of success.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.netguru.com/blog/enterprise-ai-projects-fail-root-causes&quot;&gt;Continue reading on &lt;strong&gt;www.netguru.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-26T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/why-enterprise-ai-projects-fail-5-root-causes-fixes</id>
    <title>🔗 Why enterprise AI projects fail: 5 root causes &amp; fixes</title>
    <updated>2026-06-26T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/what-is-ai-governance" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;AI governance is becoming essential as organizations increasingly rely on AI for critical functions. A recent report highlighted that 60% of organizations have AI agents in production, but 40% see security and compliance as the top barrier to scaling. This gap illustrates the urgent need for a governance framework that aligns AI development with ethical, legal, and operational standards.&lt;/p&gt;
&lt;p&gt;Effective AI governance addresses risks, ensures compliance, and fosters user trust by instituting clear rules and ongoing monitoring throughout the AI lifecycle. It incorporates principles such as transparency, accountability, and fairness to counter biases in AI models and management of sensitive data.&lt;/p&gt;
&lt;p&gt;With regulatory landscapes evolving rapidly—including the EU&apos;s AI Act and the NIST AI Risk Management Framework—an established governance strategy becomes even more critical for organizations aiming to harness AI safely and responsibly.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.docker.com/blog/what-is-ai-governance/&quot;&gt;Continue reading on &lt;strong&gt;www.docker.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/auth&quot;&gt;#auth&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-25T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/what-is-ai-governance</id>
    <title>🔗 What is AI governance?</title>
    <updated>2026-06-25T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/how-erlangs-parser-tools-saved-my-dsmr-library" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Have you ever been buried under a maze of regex and string operations? Robin van der Vleuten shares how he faced this dilemma while working on a DSMR library for smart meter data. Initially relying on chaotic regex patterns, van der Vleuten struggled with parsing errors and maintenance challenges. The breakthrough came when he discovered Erlang&apos;s &lt;code&gt;leex&lt;/code&gt; and &lt;code&gt;yecc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These tools allowed him to define clear patterns and grammar rules, transforming the parsing process into a more declarative approach. By separating concerns, enhancing error reporting, and improving performance, these parser tools not only streamlined his library but also reminded him of the value of established solutions in programming.&lt;/p&gt;
&lt;p&gt;The library is now open source and effectively handles various DSMR versions and smart meter types, embodying the lesson that sometimes older tools are the best fit for complex tasks.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://robinvdvleuten.nl/post/how-erlangs-parser-tools-saved-my-dsmr-library/&quot;&gt;Continue reading on &lt;strong&gt;robinvdvleuten.nl&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-25T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/how-erlangs-parser-tools-saved-my-dsmr-library</id>
    <title>🔗 How Erlang&apos;s parser tools saved my DSMR library</title>
    <updated>2026-06-25T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/ai-literacy-is-not-prompt-literacy-ann-handley-says-its-judgment-literacy" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Ann Handley argues that true AI literacy extends beyond prompt engineering to encompass judgment literacy. She highlights a critical question often overlooked in AI training: when should we refrain from using AI tools to preserve essential learning? While prompt literacy can be taught quickly, developing judgment literacy takes time and experience, as it involves understanding the value of struggle and learning.&lt;/p&gt;
&lt;p&gt;The AI training industry tends to focus on tool usage, ignoring the importance of knowing when not to use them. Handley suggests that fostering a culture of thoughtful AI usage, rather than merely offering courses, is vital for cultivating this necessary judgment.&lt;/p&gt;
&lt;p&gt;This insight shifts the emphasis from mere skills acquisition to deeper professional wisdom, stressing that the nuances of human insight remain irreplaceable in many contexts where AI tools might otherwise dominate.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.searchenginejournal.com/ai-literacy-is-not-prompt-literacy-ann-handley-says-its-judgment-literacy/577322/&quot;&gt;Continue reading on &lt;strong&gt;www.searchenginejournal.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-25T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/ai-literacy-is-not-prompt-literacy-ann-handley-says-its-judgment-literacy</id>
    <title>🔗 AI literacy is not prompt literacy. Ann Handley says it&apos;s judgment literacy</title>
    <updated>2026-06-25T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/test-coverage-wont-save-you" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;What happens when coding agents take over? In her insightful article, Jenn Cooper highlights a major flaw in relying solely on testing in AI-generated codebases. While high test coverage may seem like a safety net, it primarily locks in existing behaviors, good or bad. This can lead to a creeping architectural drift, where problematic patterns become entrenched without anyone noticing.&lt;/p&gt;
&lt;p&gt;To counter this, she advocates for fitness functions that evaluate the overall shape and coherence of the system, not just individual components. By implementing macro-level checks and creating friction during coding, teams can guide agents towards healthier coding practices and ensure a more coherent codebase. The discussion resonates with anyone tasked with maintaining code quality in an era increasingly influenced by AI.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://forestwalk.ai/blog/test-coverage-wont-save-you-from-incoherence/&quot;&gt;Continue reading on &lt;strong&gt;forestwalk.ai&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/testing&quot;&gt;#testing&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-24T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/test-coverage-wont-save-you</id>
    <title>🔗 Test coverage won&apos;t save you</title>
    <updated>2026-06-24T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/how-i-use-llms-as-a-staff-engineer-in-2026" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;A year can bring significant changes in technology use. In this article, the author reflects on how they leverage large language models (LLMs) as a staff engineer in 2026, detailing a notable enhancement in efficiency and accuracy. Tasks that once required close supervision, such as writing code changes and debugging, have become more streamlined with current models that can analyze complex problems independently.&lt;/p&gt;
&lt;p&gt;The article highlights a shift from skepticism to reliance, with LLMs now effectively handling routine tasks while the engineer focuses on strategic judgment. The author notes routine usage for investigating bugs and generating pull requests, while still emphasizing the importance of human oversight when it comes to critical communications and UI testing. As LLM technology evolves, the balance of delegation and supervision remains a key consideration.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.seangoedecke.com/how-i-use-llms-in-2026/&quot;&gt;Continue reading on &lt;strong&gt;www.seangoedecke.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-24T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/how-i-use-llms-as-a-staff-engineer-in-2026</id>
    <title>🔗 How I use LLMs as a staff engineer in 2026</title>
    <updated>2026-06-24T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/how-to-write-garbage-code-by-linus-torvalds" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Linus Torvalds recently criticized a Meta engineer for submitting subpar code late in a merge window, calling it &quot;garbage&quot;. He emphasized that good code should minimize cognitive load for all readers, including software engineers and LLMs. By reducing unnecessary abstractions and helper functions, developers can maintain clarity and simplicity in their code. This approach aligns with the PRY principle of repeating oneself to enhance comprehension.&lt;/p&gt;
&lt;p&gt;The article underscores that task-switching incurs cognitive costs, suggesting sometimes duplication may actually help rather than hinder understanding. It also highlights that being rude about code failures can discourage contributions, advocating for a more supportive and constructive coding environment.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://read.engineerscodex.com/p/how-to-not-write-garbage-code-by&quot;&gt;Continue reading on &lt;strong&gt;read.engineerscodex.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/git&quot;&gt;#git&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-24T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/how-to-write-garbage-code-by-linus-torvalds</id>
    <title>🔗 How to write &quot;garbage code&quot; (by Linus Torvalds)</title>
    <updated>2026-06-24T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/build-an-mcp-server-with-laravel-and-use-it-to-publish-this-post" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Every MCP server tutorial you&apos;ll find is written in Python or TypeScript. If you&apos;re a Laravel developer, you&apos;ve been left out of the conversation — until now. Laravel&apos;s official &lt;code&gt;laravel/mcp&lt;/code&gt; package lets you build MCP servers that expose your application&apos;s functionality directly to AI assistants like Claude. This setup eliminates traditional concerns like REST API design and authentication tokens. In just about 20 minutes, the author created an MCP server to manage this very blog post.&lt;/p&gt;
&lt;p&gt;The article dives into the Model Context Protocol (MCP), an open standard that enables AI assistants to perform structured actions with clear inputs and outputs. With Laravel&apos;s support for both &lt;code&gt;stdio&lt;/code&gt; and &lt;code&gt;HTTP&lt;/code&gt; transports, users can effortlessly query, create, update, and publish blog posts, all without navigating a browser. From tools like &lt;code&gt;CreatePostTool&lt;/code&gt; to &lt;code&gt;PublishPostTool&lt;/code&gt;, each section details simple class implementations, helping developers seamlessly integrate AI interactions with their Laravel applications.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://thunk.dev/posts/build-mcp-server-with-laravel&quot;&gt;Continue reading on &lt;strong&gt;thunk.dev&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/php&quot;&gt;#php&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-23T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/build-an-mcp-server-with-laravel-and-use-it-to-publish-this-post</id>
    <title>🔗 Build an MCP server with Laravel (and use it to publish this post)</title>
    <updated>2026-06-23T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/software-engineering-discipline-and-posture" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;There’s something quietly dignified about a clean commit history and well-written documentation. This article by Blain Smith emphasizes that engineering discipline is rooted in respect for teammates. Respect isn&apos;t just a thumbs-up emoji; it’s about naming variables wisely and writing comprehensive documentation that doesn’t assume prior knowledge.&lt;/p&gt;
&lt;p&gt;Commits serve as ongoing conversations, not merely logs of activity. Each commit message should prioritize clarity, recognizing that it may be read long after its creation. Pull requests are portrayed as invitations for collaboration, requiring context and clarity rather than vague demands. The piece stresses the importance of making improvements every time code is touched, no matter how small. Ultimately, engineering transcends merely shipping features; it’s about enhancing the experience for future developers, thus advocating for a respectful, disciplined approach to software craftsmanship.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://blainsmith.com/articles/software-engineering-discipline-and-posture/&quot;&gt;Continue reading on &lt;strong&gt;blainsmith.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/git&quot;&gt;#git&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-23T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/software-engineering-discipline-and-posture</id>
    <title>🔗 Software engineering discipline and posture</title>
    <updated>2026-06-23T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/pair-programming-is-a-cheat-code" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Pair-programming is often called a cheat code for developers and businesses alike. It not only accelerates decision-making but also promotes real-time code reviews and knowledge transfer. Instead of enduring lengthy pull-request reviews, pairs can bounce ideas off one another immediately, reducing the risk of expensive changes late in the development cycle.&lt;/p&gt;
&lt;p&gt;Additionally, frequently rotating pairs helps prevent knowledge silos, ensuring that no single developer is solely responsible for critical areas of the codebase. This method also serves as an effective teaching tool for junior developers, allowing them to absorb best practices quickly. In a world increasingly influenced by AI, maintaining this collaborative practice becomes crucial for keeping skills and knowledge current.&lt;/p&gt;
&lt;p&gt;Overall, the benefits of pair-programming are clear, encouraging teams to embrace it more fully for long-term success.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.germanvelasco.com/blog/pair-programming-is-a-cheat-code&quot;&gt;Continue reading on &lt;strong&gt;www.germanvelasco.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/pattern&quot;&gt;#pattern&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-23T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/pair-programming-is-a-cheat-code</id>
    <title>🔗 Pair-programming is a cheat code</title>
    <updated>2026-06-23T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/genserver-state-management-in-elixir-a-production-order-book" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;One GenServer manages critical aspects of trading like open positions, pending orders, and strategy state in real-time systems. This article highlights the state struct that powers the &lt;code&gt;RealtimeTrader&lt;/code&gt;, which functions as a session-scoped process in a trading pipeline. It breaks down the state management into three essential categories: runtime data comprising orders and account balance, collaborator references for dependency management, and operational flags that control system behavior.&lt;/p&gt;
&lt;p&gt;The article emphasizes design choices that allow strategies to maintain state effectively and how important features like trading flags can prevent system errors, ensuring trading activities run smoothly. Furthermore, readers gain access to full source code, enabling them to see production-grade implementations directly in action.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://seriousalchemy.com/genserver-living-order-book/&quot;&gt;Continue reading on &lt;strong&gt;seriousalchemy.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/pattern&quot;&gt;#pattern&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-22T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/genserver-state-management-in-elixir-a-production-order-book</id>
    <title>🔗 GenServer state management in Elixir: A production order book</title>
    <updated>2026-06-22T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/concurrent-reads-serialized-writes-with-genserver-and-registry" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;GenServer is often a beginner&apos;s first encounter with Elixir, but common pitfalls can arise, especially concerning data access patterns. This article highlights an issue when using &lt;code&gt;GenServer.call&lt;/code&gt; for reading data as it serializes requests, blocking concurrent access and affecting performance, such as the refresh timer for data.&lt;/p&gt;
&lt;p&gt;The solution involves utilizing &lt;code&gt;Registry&lt;/code&gt;, which allows registering processes and storing data without the complexities of managing ETS lifecycle. By implementing a &lt;code&gt;via&lt;/code&gt; tuple, the &lt;code&gt;GenServer&lt;/code&gt; can store its state in &lt;code&gt;Registry&lt;/code&gt;, enabling concurrent read access. The article provides a practical example with the FXRates module demonstrating how to effectively use &lt;code&gt;Registry&lt;/code&gt; to facilitate concurrent reads while still serializing writes. This approach not only optimizes access patterns but simplifies code management as well.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://distantprovince.by/posts/concurrent-reads-serialized-writes-with-genserver-and-registry/&quot;&gt;Continue reading on &lt;strong&gt;distantprovince.by&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/pattern&quot;&gt;#pattern&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-22T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/concurrent-reads-serialized-writes-with-genserver-and-registry</id>
    <title>🔗 Concurrent reads, serialized writes with GenServer and Registry</title>
    <updated>2026-06-22T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-beginning-of-programming-as-well-know-it" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;In the wake of AI coding assistants like Claude and Codex, many wonder if the role of a computer programmer is coming to an end. While it seems AI can perform tasks in minutes, it is not time to count human programmers out. Currently, human developers are essential for overseeing AI outputs because they infuse wisdom and creativity, which AI lacks.&lt;/p&gt;
&lt;p&gt;Although there are many success stories of AI constructing applications from specifications, they often overshadow numerous AI failures that produce unusable code. The reality is that AI-generated code cannot be deemed complete until a human reviews and corrects it. Adopting a healthy skepticism towards AI outputs will help developers maintain quality standards.&lt;/p&gt;
&lt;p&gt;As the landscape evolves, those who leverage AI effectively without relinquishing control will likely remain indispensable in their roles. This mantra echoes across all creative professions, reminding us that human oversight is paramount in the face of advancing technology.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://bitsplitting.org/2026/04/01/the-beginning-of-programming-as-well-know-it/&quot;&gt;Continue reading on &lt;strong&gt;bitsplitting.org&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-22T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-beginning-of-programming-as-well-know-it</id>
    <title>🔗 The beginning of programming as we’ll know it</title>
    <updated>2026-06-22T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/rust-vs-go-comparison" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Oh no, not another &apos;Is Rust better than Go?&apos; article. Seriously, haven&apos;t we all had our fill of these comparisons by now? But before you sigh in exasperation, hear us out!&lt;/p&gt;
&lt;p&gt;Many comparisons between Go and Rust emphasize their differences in syntax and the initial learning curve. However, ultimately, what matters is the ease of use for non-trivial projects.&lt;/p&gt;
&lt;p&gt;Since we are a platform-as-a-service provider, we think that we can contribute the most by showing you how to build a small web service in both languages. We will use the same task and popular libraries for both languages to compare the solutions side-by-side so that you can make up your own mind and get a feel for what it&apos;s like to work in each ecosystem.&lt;/p&gt;
&lt;p&gt;So, before you dismiss this as &apos;just another comparison&apos;, give it a read. There might be some details that other comparisons have missed before.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://www.shuttle.dev/blog/2023/09/27/rust-vs-go-comparison&quot;&gt;Continue reading on &lt;strong&gt;www.shuttle.dev&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/golang&quot;&gt;#golang&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/rust&quot;&gt;#rust&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-21T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/rust-vs-go-comparison</id>
    <title>🔗 Rust vs Go: A hands-on comparison</title>
    <updated>2026-06-21T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/reading-a-200k-line-codebase-you-didn-x27-t-write-a-field-guide" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Is it really possible to understand a sprawling 200,000-line codebase that someone else authored? Christoph Beck&apos;s article presents a practical guide to tackling inherited code through a systematic approach. Starting without diving directly into the files, Beck emphasizes the importance of first interpreting the project&apos;s structure, including the directory tree, dependency manifests, CI configuration, and git history.&lt;/p&gt;
&lt;p&gt;By pairing human intuition with coding agents, developers can uncover insights about the codebase&apos;s history and current state. The article details how to analyze project components efficiently, looking for clues that highlight the team’s practices and any lurking issues. With quick commands and thoughtful interpretation, readers gain a comprehensive understanding of how a legacy codebase functions before they read a single line of code.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://bitcrowd.dev/reading-a-200k-line-codebase-you-did-not-write-a-field-guide/&quot;&gt;Continue reading on &lt;strong&gt;bitcrowd.dev&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/git&quot;&gt;#git&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-21T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/reading-a-200k-line-codebase-you-didn-x27-t-write-a-field-guide</id>
    <title>🔗 Reading a 200k-line codebase you didn&apos;t write: a field guide</title>
    <updated>2026-06-21T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/claude-talk-small-code-still-big" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;AI coding assistants often provide lengthy explanations with every change. But what if they cut down on chatter?&lt;/p&gt;
&lt;p&gt;The author shares their experience using the &quot;Caveman&quot; skill, which simplifies AI output to short, effective phrases like &quot;Me fix bug&quot;. While this approach saved tokens, the actual savings were less than anticipated.&lt;/p&gt;
&lt;p&gt;Most tokens are spent on reading files and generating code, rather than on explanations alone. Despite this, there&apos;s merit in the brevity for simple tasks, keeping reviews light-hearted and efficient.&lt;/p&gt;
&lt;p&gt;However, for more complex changes, traditional communication is still essential to capture important context.&lt;/p&gt;
&lt;p&gt;In conclusion, while the Caveman skill doesn&apos;t revolutionize AI coding assistants, it provides a lighter, more amusing way to handle quick tasks.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://spatie.be/blog/claude-talk-small-code-still-big&quot;&gt;Continue reading on &lt;strong&gt;spatie.be&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-21T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/claude-talk-small-code-still-big</id>
    <title>🔗 Claude talk small. Code still big.</title>
    <updated>2026-06-21T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/oauth-2-0-device-flow-explained-for-engineers-especially-for-backend-engineers" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;A frustrating login experience with long passwords on devices led to the development of OAuth 2.0 device flow. This flow provides a practical solution for scenarios where typing passwords is unfeasible, such as on smart TVs or IoT devices.&lt;/p&gt;
&lt;p&gt;The article details how to implement this flow step-by-step using a command-line interface called &lt;code&gt;mycli&lt;/code&gt;. It breaks down how to handle the authorization process effectively, manages polling, and explains the various server responses that developers must anticipate.&lt;/p&gt;
&lt;p&gt;With real-world examples of how this flow enhances user experience, the piece serves as a guide for backend engineers to streamline authentication processes for users facing input constraints, ultimately urging developers to implement it in their applications.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://stackoverflow.blog/2026/05/11/oauth-2-0-device-flow-explained-for-engineers-especially-for-backend-engineers/&quot;&gt;Continue reading on &lt;strong&gt;stackoverflow.blog&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/http&quot;&gt;#http&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/auth&quot;&gt;#auth&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-20T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/oauth-2-0-device-flow-explained-for-engineers-especially-for-backend-engineers</id>
    <title>🔗 OAuth 2.0 – device flow explained for engineers, especially for backend engineers</title>
    <updated>2026-06-20T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/laravel-mcp-getting-started" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Your AI coding agent writes better code when it has real context about your application.&lt;/p&gt;
&lt;p&gt;This article examines the Laravel MCP, which provides a structured way to expose your app’s capabilities to AI clients, like ChatGPT and Claude. Without MCP, AI agents can misinterpret your app&apos;s architecture, causing them to guess column names and routes. By utilizing the &lt;code&gt;laravel/mcp&lt;/code&gt; package, developers can build an MCP server that allows their applications to interact intelligently with AI.&lt;/p&gt;
&lt;p&gt;This starts to shine when integrating with non-technical users, simplifying data access without needing knowledge of APIs or CLI calls. The piece also covers practical steps for setting up an MCP server, tools, resources, prompts, and authentication methods, ensuring that readers can effectively harness AI to interact seamlessly with their Laravel applications.&lt;/p&gt;
&lt;p&gt;It drives home the importance of structured integration as development scales, particularly in enterprise environments.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://laravel.com/blog/laravel-mcp-a-complete-guide&quot;&gt;Continue reading on &lt;strong&gt;laravel.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/laravel&quot;&gt;#laravel&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/php&quot;&gt;#php&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-20T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/laravel-mcp-getting-started</id>
    <title>🔗 Laravel MCP: Getting started</title>
    <updated>2026-06-20T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/credence-elixir-semantic-linter" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;A semantic linter for LLM-generated Elixir code.&lt;/p&gt;
&lt;p&gt;Elixir&apos;s compiler checks syntax. Credo checks style. Credence checks semantics — it mainly catches patterns that compile and pass tests but are non-idiomatic, inefficient, or ported from Python/JavaScript conventions that don&apos;t belong in Elixir.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://hex.pm/packages/credence&quot;&gt;Continue reading on &lt;strong&gt;hex.pm&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/tools&quot;&gt;#tools&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/elixir&quot;&gt;#elixir&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-20T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/credence-elixir-semantic-linter</id>
    <title>🔗 Credence: Elixir semantic linter</title>
    <updated>2026-06-20T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-tacit-dimension-why-your-best-engineers-cant-tell-you-what-they-know" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;In today&apos;s software development landscape, the tacit knowledge held by experienced engineers is undervalued and often overlooked. This article argues that while explicit knowledge is easily documented and processed by AI, the intuitive insights and patterns recognized by seasoned developers are impossible to articulate or transfer effectively to artificial intelligence.&lt;/p&gt;
&lt;p&gt;The piece draws on Michael Polanyi&apos;s concept of tacit knowledge to illustrate how many crucial understandings in engineering cannot be reduced to written words. As teams increasingly rely on AI for coding tasks, there&apos;s a rising danger of losing this invaluable insight, which could leave future engineers ill-equipped to navigate complex codebases.&lt;/p&gt;
&lt;p&gt;The author warns that, without intentional mentorship and collaboration, the next generation could experience a decline in critical thinking and problem-solving skills, making the role of experienced engineers more essential than ever.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://cekrem.github.io/posts/the-tacit-dimension/&quot;&gt;Continue reading on &lt;strong&gt;cekrem.github.io&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-19T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-tacit-dimension-why-your-best-engineers-cant-tell-you-what-they-know</id>
    <title>🔗 The tacit dimension: why your best engineers can&apos;t tell you what they know</title>
    <updated>2026-06-19T17:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/ais-impact-on-software-engineers-in-2026-key-trends-part-2" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;What if AI tools not only boost productivity but also lead to decreased code quality? In this concluding part of the series, Gergely Orosz and Elin Nilsson delve into the findings from over 900 survey responses regarding AI&apos;s effects on software engineers by 2026. They reveal that while AI can reduce the time spent on routine tasks, it introduces new challenges like unrealistic expectations and quality issues.&lt;/p&gt;
&lt;p&gt;Many companies struggle with large-scale adoption, finding that effective AI use depends heavily on existing engineering practices. Engineers report a decline in codebase quality, with more bugs sneaking into projects and less experienced programmers grappling with AI-generated code. The piece emphasizes the need for robust guidelines and highlights the complex influence of AI on collaboration, highlighting varying impacts based on individual adaptability and team culture.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://newsletter.pragmaticengineer.com/p/ai-impact-on-software-engineers-part-2&quot;&gt;Continue reading on &lt;strong&gt;newsletter.pragmaticengineer.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/ai&quot;&gt;#ai&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-19T13:00:00Z</published>
    <id>https://www.yellowduck.be/posts/ais-impact-on-software-engineers-in-2026-key-trends-part-2</id>
    <title>🔗 AI’s impact on software engineers in 2026: key trends, Part 2</title>
    <updated>2026-06-19T13:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/high-performance-git" rel="alternate"/>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Git serves multiple roles beyond just version control; it operates as a content-addressed database, a filesystem cache, and more. This article dives into the different layers of Git, discussing the performance implications of objects, refs, the index, and history traversal. It covers advanced topics like packfiles, maintenance, sparse working trees, and the nuances of partial cloning.&lt;/p&gt;
&lt;p&gt;Written specifically for engineers—particularly those in build, CI, and developer experience roles—the content highlights the importance of maintaining speed and efficiency as repositories grow in size and complexity. It offers insights into diagnosis, configuration, and recovery, making it a valuable resource for anyone managing Git at scale.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://gitperf.com/&quot;&gt;Continue reading on &lt;strong&gt;gitperf.com&lt;/strong&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/reading-list&quot;&gt;#reading-list&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/development&quot;&gt;#development&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/devops&quot;&gt;#devops&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/git&quot;&gt;#git&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-19T08:00:00Z</published>
    <id>https://www.yellowduck.be/posts/high-performance-git</id>
    <title>🔗 High performance Git</title>
    <updated>2026-06-19T08:00:00Z</updated>
  </entry>
  <entry>
    <author>
      <name>Pieter Claerhout</name>
      <email>pieter@yellowduck.be</email>
    </author>
    <link href="https://www.yellowduck.be/posts/the-mysql-null-safe-equality-operator" rel="alternate"/>
    <content type="html">&lt;p&gt;If you&apos;ve worked with MySQL long enough, you&apos;ve probably been bitten by &lt;code&gt;NULL&lt;/code&gt; comparisons at least once. A query that &lt;em&gt;should&lt;/em&gt; return results returns nothing. A &lt;code&gt;WHERE&lt;/code&gt; clause that &lt;em&gt;should&lt;/em&gt; exclude a row doesn&apos;t. The culprit is almost always the three-valued logic of SQL — and the null-safe equality operator &lt;code&gt;&lt;=&gt;&lt;/code&gt; is one of the cleanest tools for dealing with it.&lt;/p&gt;
&lt;h1&gt;The problem with &lt;code&gt;=&lt;/code&gt; and &lt;code&gt;NULL&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;In SQL, &lt;code&gt;NULL&lt;/code&gt; represents the absence of a value — the unknown. Because of this, any comparison involving &lt;code&gt;NULL&lt;/code&gt; using the standard &lt;code&gt;=&lt;/code&gt; operator yields &lt;code&gt;NULL&lt;/code&gt; (not &lt;code&gt;TRUE&lt;/code&gt; or &lt;code&gt;FALSE&lt;/code&gt;), and &lt;code&gt;NULL&lt;/code&gt; is falsy in a &lt;code&gt;WHERE&lt;/code&gt; clause.&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;   -- NULL
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;      -- NULL
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;         -- 1 (TRUE)
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;deleted_at&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;  -- returns nothing
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The idiomatic fix is &lt;code&gt;IS NULL&lt;/code&gt; / &lt;code&gt;IS NOT NULL&lt;/code&gt;, but that only works for literal null checks. The moment you&apos;re comparing two columns — one or both of which might be &lt;code&gt;NULL&lt;/code&gt; — things get awkward fast.&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;text&quot;&gt;-- This silently drops rows where either column is NULL
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;orders&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;shipping_address&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;billing_address&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Enter &lt;code&gt;&lt;=&gt;&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;MySQL&apos;s null-safe equality operator &lt;code&gt;&lt;=&gt;&lt;/code&gt; behaves exactly like &lt;code&gt;=&lt;/code&gt;, except it treats &lt;code&gt;NULL&lt;/code&gt; as a comparable value. Two &lt;code&gt;NULL&lt;/code&gt;s are considered equal, and a &lt;code&gt;NULL&lt;/code&gt; compared to any non-null value is &lt;code&gt;FALSE&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&lt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;   -- 1 (TRUE)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;type-builtin&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&lt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;      -- 0 (FALSE)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&lt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;         -- 1 (TRUE)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&lt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;         -- 0 (FALSE)
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes it safe to compare nullable columns directly:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;text&quot;&gt;-- Correctly includes rows where both columns are NULL
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;orders&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;shipping_address&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&lt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;billing_address&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;A real-world example&lt;/h1&gt;
&lt;p&gt;Consider a polymorphic &lt;code&gt;subscriptions&lt;/code&gt; join table that maps users to subscribable entities (posts, documents, threads, etc.). The goal: return all subscribers &lt;em&gt;excluding&lt;/em&gt; the item&apos;s author, even when &lt;code&gt;author_id&lt;/code&gt; might be &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The naive approach breaks silently:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;text&quot;&gt;WHERE subscriptions&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;user_id &lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;text&quot;&gt; posts&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;author_id
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When &lt;code&gt;author_id&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt;, this evaluates to &lt;code&gt;NULL&lt;/code&gt;, so the row is dropped — meaning a user who subscribes to a post with no author would incorrectly disappear from the result.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The null-safe fix:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;text&quot;&gt;NOT &lt;/span&gt;&lt;span class=&quot;punctuation-bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;subscriptions&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;text&quot;&gt;user_id &lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&lt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;punctuation-bracket&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;author_id&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;posts&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;variable-member&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;subscriptions&lt;/span&gt;&lt;span class=&quot;punctuation-delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;variable-member&quot;&gt;item_id&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span class=&quot;punctuation-bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation-bracket&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This reads as: &lt;em&gt;&quot;keep this row unless the subscriber&apos;s user_id exactly matches the author_id, treating NULL as a concrete equal value.&quot;&lt;/em&gt; When &lt;code&gt;author_id&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt; and &lt;code&gt;user_id&lt;/code&gt; is not, the &lt;code&gt;&lt;=&gt;&lt;/code&gt; returns &lt;code&gt;FALSE&lt;/code&gt;, so &lt;code&gt;NOT FALSE&lt;/code&gt; is &lt;code&gt;TRUE&lt;/code&gt; — the row is kept. Correct behaviour in all cases.&lt;/p&gt;
&lt;h1&gt;&lt;code&gt;&lt;=&gt;&lt;/code&gt; vs. the alternatives&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Handles NULL?&lt;/th&gt;
&lt;th&gt;Readable?&lt;/th&gt;
&lt;th&gt;Standard SQL?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;col = val&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;col IS NULL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes (literal only)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;COALESCE(col, &apos;&apos;) = COALESCE(val, &apos;&apos;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes (with sentinel)&lt;/td&gt;
&lt;td&gt;Passable&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(col = val OR (col IS NULL AND val IS NULL))&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Verbose&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;col &lt;=&gt; val&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (MySQL/MariaDB)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;code&gt;COALESCE&lt;/code&gt; sentinel approach is fragile — you need to pick a value that can never appear in real data. The verbose &lt;code&gt;OR (IS NULL AND IS NULL)&lt;/code&gt; pattern works but is noisy. &lt;code&gt;&lt;=&gt;&lt;/code&gt; wins on brevity and correctness, at the cost of portability.&lt;/p&gt;
&lt;h1&gt;When to use it&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;&lt;=&gt;&lt;/code&gt; is a good fit when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Comparing two nullable columns&lt;/strong&gt; directly in a &lt;code&gt;WHERE&lt;/code&gt; or &lt;code&gt;JOIN&lt;/code&gt; condition.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Negating equality on nullable data&lt;/strong&gt; (&lt;code&gt;NOT (a &lt;=&gt; b)&lt;/code&gt; is cleaner than the alternative).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upsert / deduplication queries&lt;/strong&gt; where you need exact matching including null identity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generated columns or audit logic&lt;/strong&gt; where you want to detect whether a value actually changed, including transitions to/from &lt;code&gt;NULL&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Caveats&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;MySQL and MariaDB only.&lt;/strong&gt; The &lt;code&gt;&lt;=&gt;&lt;/code&gt; operator is not part of the SQL standard and is not available in PostgreSQL, SQLite, or SQL Server. If your codebase runs tests against SQLite (a common Laravel setup), any &lt;code&gt;&lt;=&gt;&lt;/code&gt; in a raw query will fail there.&lt;/p&gt;
&lt;p&gt;PostgreSQL&apos;s equivalent is &lt;code&gt;IS NOT DISTINCT FROM&lt;/code&gt; / &lt;code&gt;IS DISTINCT FROM&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-sql&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span class=&quot;text&quot;&gt;-- PostgreSQL equivalent of &lt;=&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;col &lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;keyword-operator&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;DISTINCT&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;text&quot;&gt; val
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;-- PostgreSQL equivalent of NOT (col &lt;=&gt; val)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;col &lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;DISTINCT&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;text&quot;&gt; val
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If cross-database portability matters, abstract the comparison behind a query scope or use the verbose but portable &lt;code&gt;OR (IS NULL AND IS NULL)&lt;/code&gt; form.&lt;/p&gt;
&lt;h1&gt;Summary&lt;/h1&gt;
&lt;p&gt;The null-safe equality operator &lt;code&gt;&lt;=&gt;&lt;/code&gt; is one of those small MySQL features that, once you know it exists, saves you from a whole class of subtle bugs. It&apos;s most valuable when you need to compare nullable columns directly — particularly in negated conditions where the standard &lt;code&gt;!=&lt;/code&gt; would silently swallow &lt;code&gt;NULL&lt;/code&gt; rows. Just keep portability in mind: it&apos;s a MySQL/MariaDB extension, so make sure your test database matches your production database before reaching for it.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/tags/best-practice&quot;&gt;#best-practice&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/mysql&quot;&gt;#mysql&lt;/a&gt; &lt;a href=&quot;https://www.yellowduck.be/tags/sql&quot;&gt;#sql&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-06-18T17:00:00Z</published>
    <id>https://www.yellowduck.be/posts/the-mysql-null-safe-equality-operator</id>
    <title>🐥 The MySQL null-safe equality operator: &lt;=&gt;</title>
    <updated>2026-06-18T17:00:00Z</updated>
  </entry>
</feed>