惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
J
Java Code Geeks
I
InfoQ
V
Visual Studio Blog
M
MIT News - Artificial intelligence
H
Help Net Security
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
人人都是产品经理
人人都是产品经理
G
Google Developers Blog
A
About on SuperTechFans
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
云风的 BLOG
云风的 BLOG
S
SegmentFault 最新的问题
WordPress大学
WordPress大学

Lobsters

CIFSwitch: a non-universal Linux local root vulnerability RIPE NCC session fixation: poaching logins with an Atlas probe GNOME 2.20 but its Web Components Agentic Search for Context Engineering – Leonie Monigatti Garnix is shutting down [not OC] akashina.tngl.sh/jjc Concerning Emacs (and Jazz) Nitpicking the shell history scene in ‘Tron: Legacy’ What's cooking on SourceHut? Q2 2026 The tenth OpenPGP email summit Package managers that package package managers Clojure on Fennel part three: parsing WordPress at 23 Finding Miscompiles for Fun, Not Profit GitHub - creusot-rs/creusot: Creusot helps you prove your Rust code is correct. Announcing Rust 1.96.0 | Rust Blog A Love Letter to Neovim sqlite AGENTS.md Am I a Bad Friend? CSS vs. JavaScript • Josh W. Comeau Erlang Ecosystem Foundation - Supporting the BEAM community A brief note about slot access cost in Common Lisp Keyboard latency probe Rethinking the GNOME clipboard issues Back to the Building Blocks’ Building Blocks Tech Notes: Theseus: translating win32 to wasm Fast is better than slow Content-addressed Rust builds (or, what kache actually caches) Intent to Prototype: Embedding API Canada’s Bill C-22 and the security cost of collecting more data
Stop Naming Your Variables "Flag": The Art of Boolean Pre...
Christopher Johnson · 2026-06-19 · via Lobsters

Shallow Focus Flags

The Problem

You inherit a codebase and find this:

public class OrderProcessor
{
    private bool open;
    private bool flag;
    private bool done;
    private bool status;
    
    public void Process(bool check)
    {
        if (open && flag)
        {
            flag = false;
            status = true;
        }
        
        if (done)
        {
            // what happens here?
        }
    }
}

Readable? No.

What is open? Is the store open? Should the file open? What is flag? That’s a variable screaming “I’ll fix this later.” And is done a question (“is it done?”) or a command (“mark it done”)?

Boolean names are ambiguous land mines. They look innocent until you have to figure out what they mean during a 3 AM outage.

Ambiguity breeds bugs. A reviewer looks at if (done) and guesses the intent. A maintainer rewrites flag = false and accidentally inverts logic they didn’t understand. if (!flag)… does that mean turn it on? Turn it off?

Boolean names matter because they aren’t abstract labels; they are questions. Your code asks the question, and the boolean value answers “yes” or “no.” If the variable name isn’t a clear question, the answer is meaningless.

The Solution: The 4 Prefixes

You can cover 99% of boolean naming scenarios with just four prefixes. If you stick to these, every boolean becomes a clear, grammatical question.

1. IS: Identity and State Use is when describing what something is right now. It usually pairs with an adjective.

  • Good: isActive, isDeleted, isEmpty.
  • Bad: isAccess (Grammar mismatch. Use hasAccess).

2. HAS: Containment and Features Use has when describing ownership or inclusion. It pairs with a noun.

  • Good: hasAccess, hasChildren, hasValidationErrors.
  • Bad: hasActive (Grammar mismatch. Use isActive).

3. CAN: Capability Use can to check permissions or potential actions.

  • Good: canEdit, canDelete, canRetry.
  • Bad: canAdmin (Vague. Use isAdmin or canAdminister).

4. SHOULD: Intent Use should for business rules or decisions the system needs to make. This separates “what we can do” from “what we want to do.”

  • Good: shouldRetry, shouldCacheResponse.
  • Bad: shouldUser (Incomplete. shouldCreateUser?).

Stick to this list. When you mix them up—like writing isAccess or hasActive—you force the reader to stop and re-parse the sentence in their head. That friction is where bugs get introduced.

PrefixDomainFunctionExample
ISIdentity / StateDescribes what an object is currently.isActive, isEmpty
HASContainmentDescribes ownership or feature presence.hasChildren, hasAccess
CANCapabilityDescribes permission or potential action.canEdit, canRetry
SHOULDIntent / LogicDescribes a business rule recommendation.shouldCache, shouldRetry

The “No Negatives” Rule

Here is the most important rule: Never use negation in the variable name.

Avoid names like isNotEnabled, hasNoAccess, or isDisabled.

Why? Because eventually, you will need to check for the opposite state. if (!isDisabled) forces your brain to calculate a double negative: “If not is disabled…”

Compare that to: if (isEnabled)

Immediate clarity.

Negative names feel natural when you write them (“I need to check if this is disabled”), but they are a tax on every person who reads the code later. Refactoring tools make this worse; if you invert an if statement, your IDE might helpfully rename isDisabled to isNotDisabled. Now you have code that is actively hostile to human readers.

The Exception: The only time a negative name is acceptable is when you are mirroring an external API or HTML attribute that is negative by default, like noValidate. Even then, isolate it at the boundary. In your domain logic, always map it to a positive: bool shouldValidate = !request.noValidate.

Context Matters (The “Boolean Trap”)

The rules above work perfectly for properties (state). They fall apart for parameters (function arguments).

This is the “Boolean Trap”:

// Real code from NHibernate
schemaExport.Execute(false, true, false);

Quick: What does the second true do? You have no idea. You have to open the library source code to find out.

If you see a method signature like Execute(bool, bool, bool), you are looking at a design bug.

How to fix it:

1. Split the method If the boolean changes the method’s behavior entirely, make two methods.

// Bad
email.Send(message, true); // is true "immediate"? "high priority"?

// Good
email.SendImmediately(message);
email.SendQueued(message);

2. Use an Enum If there are modes, name them.

// Bad
file.Write(data, true);

// Good
file.Write(data, WriteMode.Append);

3. Use a Config Object If you have multiple flags, pass an object.

// Bad
export.Execute(false, true, false);

// Good
export.Execute(new ExportOptions { 
    Script = false, 
    Export = true, 
    JustDrop = false 
});

The Antipatterns

If you want to clean up your code, watch out for these specific smells in code reviews.

1. The “Shrug” Variable Names like flag, done, or check tell you nothing about what is being tracked.

  • Bad: if (check)
  • Fix: if (isPaymentVerified)

2. Mismatched Grammar Breaking the prefix rules confuses the mental model.

  • Bad: if (user.hasActive)
  • Fix: if (user.isActive)

3. The Double Negative Any time you see a ! next to a Not or No.

  • Bad: if (!isNotEnabled)
  • Fix: if (isEnabled)

4. The Multi-Purpose Boolean A single variable that secretly tracks three different things.

  • Bad: isValid (Actually checks if user exists, has email, AND is active).
  • Fix: Be explicit.
    bool isReadyForBilling = user.Exists && user.HasEmail && user.IsActive;

5. The Drifting Flag A local boolean that gets reused for different logic steps.

  • Bad:
    bool error = false;
    if (!Save()) error = true;
    if (!error && !SendEmail()) error = true;
    return error;
  • Fix: Use a Result object or return early. Don’t recycle a boolean bucket.

Conclusion

Naming isn’t about style. It’s about empathy.

When you name a boolean flag, you’re writing for yourself in the moment. When you name it isProcessed, you’re writing for the poor soul who has to fix a bug in this file six months from now. That person is probably you. Be kind to your future self.