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

Exadra37
Cloudflare as workers to run serverless code without using containers: So it seems that Isolates is based on: What we ended up settl...
New
AstonJ
Great paper by Igor Kopestenski on Erlang and GRiSP: Erlang as an Enabling Technology for Resilient General-Purpose Applications on Edge ...
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
Hi everyone… I’m so sorry about the delay in getting this thread up, I’ve just been so busy :see_no_evil: Are there any book clubs you’d...
New
dwaynebradley
For those that are interested, Snyk (developer security tool) announced support for Elixir earlier this week: Just thought I’d pass it...
New
GermaVinsmoke
Do you like to help others on stackoverflow in your free time? And what’s your reputation on Stackoverflow? :smirk::joy::rofl:
New
Margaret
Hello everyone! This thread is to tell you about what authors from The Pragmatic Bookshelf are writing on Medium.
1147 29994 760
New
harwind
I’m developing a web-based application that uses Java servlets to make RPC calls. I’m searching for a solid technique to dispatch and ha...
New
AntonRich
I don’t know what happened today. But I just started reading SICP which I meant to do for a long time. The book itself: I’m not even s...
New
Margaret
Hello DevTalk Community! Once again, The Pragmatic Programmers are looking for developers who’d like to help shape the future of our boo...
New

Other popular topics Top

PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
ohm
Which, if any, games do you play? On what platform? I just bought (and completed) Minecraft Dungeons for my Nintendo Switch. Other than ...
New
siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
PragmaticBookshelf
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
New
New
AstonJ
If you’re getting errors like this: psql: error: connection to server on socket “/tmp/.s.PGSQL.5432” failed: No such file or directory ...
New