mjk

mjk

Java by Comparison: Thoughts on "Avoid Negations" (page 4)

TL;DR: words that incorporate negation are acceptable, eg. independent, asymmetric, nondeterministic.

An example in the book is to rename isInorganic() to isOrganic(), but I think this is too mechanical and goes too far. The field of inorganic chemistry thinks of itself positively, and its domain vocabulary includes the word. More important than recognizing words that contain negation is to respect the domain terminology. Also it is more important to consider the typical usage in code. For example, when following the “Fail Fast” pattern, we expect something like this pseudocode: if isInvalid(arg) { throw new exception } I think that the authors might recognize this as they use isUnknown(), a positive statement of negation, is a later example.

I agree it is generally better to avoid negative logic, and that coders should know De Morgan’s laws (page 7), but I find it ironic that turning this

boolean isValid() {
    return missions >= 0 && name != null && !name.trim().isEmpty();
}

into

boolean isValid() {
    boolean isValidMissions = missions >= 0;
    boolean isValidName = name != null && !name.trim().isEmpty();
    return isValidMissions && isValidName;
}

is considered better than this

boolean isInvalid() {
    return missions < 0 || name == null || name.trim().isEmpty();
}

(which can be easily lambda-ized to boot).

Most Liked

Ted

Ted

I like the sentiment of the “Avoid Negations” section, especially in how negations can weasel their way into naming, but I agree with @mjk that renaming isInorganic() to isOrganic() is in fact a good cautionary tale of going too far and not considering the domain context. :thinking: Also, I think the fact that the Result.INORGANIC constant exists and couldn’t be renamed is a big clue that the term “inorganic” is probably an important domain concept.

Regarding the three-line version of isValid(), I think the book would be better served if it skipped the foreshadowing and presented it in the “Simplify Boolean Expressions” section instead of the preceding “Return Boolean Expressions Directly”, that way we can see the two approaches, i.e., introducing local vars versus extracting methods, closer together.

And perhaps this is covered later, but I also think the book misses an opportunity to suggest using libraries to simplify expressions. For example, using a string-utility library such as StringUtils in Commons Lang 3 would also simplify isValid() in a clear and concise way:

boolean isValid() {
    return missions >= 0 && StringUtils.isNotBlank(name);
}

I don’t propose adding a new dependency only for the sake of simplifying one single line of code, but in this specific example of string logic, a sizable project most likely already has such a library as a dependency.

And finally, I think the example in the “Avoid Negations” section could be carried forward into a discussion of the proper use of conditional expressions, i.e., ternaries, to get some really concise yet expressive code.

Here’s the example from the book:

class Laboratory {

    Microscope microscope;

    Result analyze(Sample sample) {
        if (microscope.isInorganic(sample)) {
            return Result.INORGANIC;
        } else {
            return analyzeOrganic(sample);
        }
    }

    private Result analyzeOrganic(Sample sample) {
        if (!microscope.isHumanoid(sample)) {
            return Result.ALIEN;
        } else {
            return Result.HUMANOID;
        }
    }
}

And here’s how it looks after inlining the private analyzeOrganic(), replacing if/else with a cascading ternary expression, flipping a negation, and applying some code formatting:

class Laboratory {

    Microscope microscope;

    Result analyze(Sample sample) {
        return
            microscope.isInorganic(sample) ? Result.INORGANIC :
            microscope.isHumanoid(sample)  ? Result.HUMANOID  :
            /* else */                       Result.ALIEN;
        }
    }

The key is to keep ternaries simple and cleanly formatted, kinda like cond in lisps such as Clojure. I love 'em! :heart_eyes:

Where Next?

Popular General Dev topics Top

AstonJ
Thought it might be worth having a dedicated thread for standing desk treadmills (for those interested, here’s our general thread on stan...
New
AstonJ
It’s great to see how popular some of these channels have become - do you have any favourite YouTuber devs? Ben Awad Code...
New
AstonJ
Inspired by this post from @Carter, which languages, frameworks or other tech or tools do you think is killing it right now? :upside_down...
New
Rainer
Not sure if following fits exactly this thread, or if we should have a hobby thread… For many years I’m designing and building model air...
New
DevotionGeo
The Odin programming language is designed with the intent of creating an alternative to C with the following goals: simplicity high per...
New
AstonJ
Things like smart speakers (such Amazon Alexa), smart TVs or other devices with built in microphones, cameras or with other features that...
New
TwistingTwists
Hello Fellow developers, I have been trying to wrap my head around How difficult would it have been to be a dev 20-30 years ago? I have...
New
AstonJ
00:00 The Year 2022 00:38 Web3 03:28 Metaverse 05:05 AI 06:22 Databases 07:31 JavaScript 09:58 Other Trends to Know WDYT - what wi...
New
ivanhercaz
Hi! I usually keep changelogs for my projects because I think they are really useful, not only to track the changes and not to be lost b...
New
harwind
I’m working on a C++ program where I need to convert a string containing a numeric value into an integer. I want to ensure that this conv...
New

Other popular topics Top

AstonJ
A thread that every forum needs! Simply post a link to a track on YouTube (or SoundCloud or Vimeo amongst others!) on a separate line an...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
AstonJ
Just done a fresh install of macOS Big Sur and on installing Erlang I am getting: asdf install erlang 23.1.2 Configure failed. checking ...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
AstonJ
Saw this on TikTok of all places! :lol: Anyone heard of them before? Lite:
New
foxtrottwist
A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New
mafinar
This is going to be a long an frequently posted thread. While talking to a friend of mine who has taken data structure and algorithm cou...
New
PragmaticBookshelf
Author Spotlight: Karl Stolley @karlstolley Logic! Rhetoric! Prag! Wow, what a combination. In this spotlight, we sit down with Karl ...
New
PragmaticBookshelf
Author Spotlight: Sophie DeBenedetto @SophieDeBenedetto The days of the traditional request-response web application are long gone, b...
New
CommunityNews
A Brief Review of the Minisforum V3 AMD Tablet. Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
New