_blackentropy

Stop Null from Ruining Your Code

Null pointers might be the single most notorious source of bugs in software history. They pop up unexpectedly, cause cryptic crashes, and lead to frantic debugging sessions that eat up your time. If you ask me, they’re a relic of lazier programming days. In my personal projects, I’ve gone all-in on null safety. Let me tell you why.


The Trillion-Dollar Mistake

It’s often said that “null” is the trillion-dollar mistake. The idea behind it was well-intentioned—denoting the absence of a value—but in practice, it’s led to more confusion and bugs than probably any other feature in modern programming. We waste countless hours checking for null values, sprinkling if (x != null) checks everywhere, or worse, forgetting to do so.

The Harsh Reality of Real-World Systems

Yes, real-world data can be messy. Yes, real systems often need to represent the unknown or incomplete. But let’s be honest: half the time those “missing” values shouldn’t even exist. They’re a symptom of sloppy schema design or rushed coding. I say if you’re the one building the system from scratch, you have the power to stamp out most nulls by design.


Strict by Default, Lenient by Exception

My approach is straightforward:

  1. Database Fields
    Make them non-null constraints by default. If your column absolutely, positively needs to store “absence of value,” consider a separate boolean or a well-defined sentinel (like an empty string). That way, you know exactly what it means when that field is “missing,” and you avoid that dreaded NULL confusion altogether.

  2. Language-Level Checks
    Use a language or framework that enforces strict null safety—think Kotlin (with ? vs non-?) or TypeScript (with strict mode enabled). These tools force you to be intentional about whether something can be null. If you mark a field or variable as non-null, the compiler will shout if you try to assign null.

  3. API Contracts
    If you’re building web services, specify required fields in your OpenAPI or JSON schema definitions. Do not let your endpoints accept half-baked requests that are only “maybe” valid. Document them thoroughly: a field is either required or it’s not. Being loose about what your service accepts only pushes complexity further downstream, multiplying your future problems.

The Edge Cases

Sure, there are legitimate cases when “nothing” or “unknown” is a meaningful state for your data. Fine—declare it, name it, and handle it properly. “Null by default” is lazy. But “null with a purpose” can be powerful. In those situations, I prefer explicitly typed enumerations or dedicated “Maybe”/“Optional” structures.


Why Slack Off?

When I bring up strict null safety, some developers balk: “But that’s too rigid. Real data is messy!” or “We can’t spend all day writing these validations.” Here’s my response: you already spend that time, just later, in the form of debugging weird edge-case bugs in production.


Is There a Point of Diminishing Returns?

Some folks ask, “Is it really worth being 100% strict?” My answer: shoot for excellence, not excuses. You might relax the rules slightly in genuinely uncontrollable third-party integrations. But for your own code, your own data, and your own APIs? You’re in control. Own it.


Embrace the Null-less Future

Null safety isn’t just a fancy language feature—it’s a mindset. Being strict from the start requires more upfront design work, but it pays off with fewer bugs, clearer contracts, and simpler code. You’ll thank yourself when you’re not wading through late-night debugging sessions chasing yet another “null pointer exception.”

So go on—banish null. Design your schemas, data contracts, and classes to be explicit. Stop letting null sneak up on you. In my world, letting nulls creep in without a fight is just not worth the hassle.