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

justinjunodev
Figured this would be a cool topic and maybe provide some inspiration for those who are just starting to work from home. Feel free to sha...
New
AstonJ
If so, what was the last blog post you wrote… and if not, why not?
New
AstonJ
If you could work on any project, what would it be? :upside_down_face:
New
mafinar
I always start with excitement and then get busy on 9/10th day. This year, like the year before this, and the year before that, I intend ...
New
AstonJ
The dev world doesn’t sit still, in fact it is probably one of the fastest paced industries around - meaning to stay current we are conti...
New
jss
What do people think about Data-Oriented Programming, like this book tackles? https://www.manning.com/books/data-oriented-programming Ho...
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
Exadra37
My brother got a VPS on https://contabo.com hosting provider, but I was not aware of them, and when my brother told me the price and spec...
New
AstonJ
Chris Seaton, the creator of TruffleRuby has died. It appears from suicide :cry: He left this note on Twitter on the weekend: And one...
New
New

Other popular topics Top

PragmaticBookshelf
Learn from the award-winning programming series that inspired the Elixir language, and go on a step-by-step journey through the most impo...
New
DevotionGeo
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
AstonJ
Or looking forward to? :nerd_face:
498 13326 269
New
dasdom
No chair. I have a standing desk. This post was split into a dedicated thread from our thread about chairs :slight_smile:
New
AstonJ
Curious to know which languages and frameworks you’re all thinking about learning next :upside_down_face: Perhaps if there’s enough peop...
New
Rainer
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
AstonJ
Thanks to @foxtrottwist’s and @Tomas’s posts in this thread: Poll: Which code editor do you use? I bought Onivim! :nerd_face: https://on...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
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
First poster: bot
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig. General-purpose programming language and toolchain for maintaini...
New