Live data from Hacker News

Clearer Conditionals using De Morgan's Laws

robots.thoughtbot.com

51–60 of 82 posts

Re: Clearer Conditionals using De Morgan's Laws

#51
post #24

Old CS students' prank: improving the "no food and drink" sign unsurprisingly often found in labs by scribbling "no (food && drink) == (no food || no drink)" on it.

Our CS labs solved that by allowing any food and drink we want. Dominos understand "the undergrad labs, ECS" as an address.

Re: Clearer Conditionals using De Morgan's Laws

#52
post #37

Earlier quoted context omitted.

Not not x is equivalent to x using the double negation rule (DN). "Not signed out" can be rephrased as "not not signed in" and thus simplified to "signed in". Same for "not untrusted ip" equaling "not not trusted ip" and, after DN, simply "trusted ip". It's completely logical, so I'm not sure what your point is. Perhaps the article should have explained this better.

The fact that "signed out" and "signed in" are opposites is not a logical fact; there's no general inference from "not p_out" to "p_in". If you had "outside" and went from !outside?" to "inside?", that would be erroneous (you could also be on the threshold). ETA: this is especially obvious for trusted/untrusted; it doesn't have to be the case that every ip is either positively trusted or positively untrusted. If, in…

OK; I see what you mean now. The article assumes the only possible states are "trusted" or "untrusted", and you disagree with that assumption.

Re: Clearer Conditionals using De Morgan's Laws

#54
This is why every developer should read Code Complete - it contains a myriad of tips learnt through many years of hard work.

Suffice to say that it contains such tips as avoiding negation in conditionals.

In the end it boils down to strategic optimization towards readability with the least mental overhead (the cycles you spend parsing, the more you can spend thinking).

Re: Clearer Conditionals using De Morgan's Laws

#55
Yep, learned that back in college, more years ago than I should admit.

Experience then teaches that if the expression is complicated enough for that to matter, you've already lost. Instead, make a boolean function with explicit "short circuit" returns.

    // return true if we're screwed
    isScrewed ( relevant parameters...):
        if failure-mode-one:
            return true
        if failure-mode-two:
            return true
        if guaranteed-save-otherwise:
            return false
        if failure-mode-three:
            return true
        return false

I remember seeing a horrible "if" statement that caused many thousands of dollars worth of wasted inventory back at one job cuz the clever coder thought he know the operator precedence and was saving time and money jamming a bunch of crap on one "if" line.

Now if I could just get coworkers to stop writing "fooFlag == true" and "fooFlag == false" :-)

Re: Clearer Conditionals using De Morgan's Laws

#56

Earlier quoted context omitted.

Interestingly I've been going back and forth on this lately. I have been playing around with SD cards on the STM32F4 and a typical SD Card transaction consists of 3 to 10 commands which, if any one fails, the transaction fails. I'm currently using negative conditionals of the form "Not Error" (the Error test is an affirmative, and so that seems ok to me) A typical sequence is like the one to set the bus width. err =…

What I've found myself doing in such cases is adding a function that processes multiple commands and indicates an error if any one of the commands failed (sdio_batch could be a varargs function): struct sdio_cmd { enum { SDIO_SELECT, SDIO_COMMAND } cmd; int reg; // Guesses at suitable names without int val; // knowing anything about SDIO } int sdio_batch(int count, ...); err = sdio_batch(3, &(struct sdio_cmd){ SDIO_S…

This is a nice structure, It also suggests something like closures where you inverse stacked the functions and did something like:

   int do_command(sdio_command_chain *cmd) {
           int err = 0;
           if (cmd->next) {
              err = do_command(cmd->next);
           }
           return (err) ? err : call_command(cmd->parms);
     }
Thanks for that!

Re: Clearer Conditionals using De Morgan's Laws

#57

This is why every developer should read Code Complete - it contains a myriad of tips learnt through many years of hard work. Suffice to say that it contains such tips as avoiding negation in conditionals. In the end it boils down to strategic optimization towards readability with the least mental overhead (the cycles you spend parsing, the more you can spend thinking).

As weird as it sounds, "or" ends up being kind of evil, and something to avoid, as well. Mix it with "and", and the result likely doesn't say what your tired brain thought it did. Also, how many "or" statements have you seen that should really be set membership tests? (it helps to have a language that makes it easy to make a literal of a set)

Re: Clearer Conditionals using De Morgan's Laws

#58
post #43
post #40

Earlier quoted context omitted.

What the sign clearly means is "no [members of the set] food and drink."

But what the sign says is either "no(food && drink)" or "no(food) && drink", depending on how you feel about precedence. The obvious implication in the first case is that either food or drink, or neither, but not both, is permissible; in the second, it's that drink is acceptable only when not also accompanied by food, but no other constraint is expressed with regard to either. If the intent was to express that neithe…

That first statement is false because English “and” is not the same thing as logical “and”.

Re: Clearer Conditionals using De Morgan's Laws

#59

Earlier quoted context omitted.

Except where writing negative conditionals are clearer. For example turning: if(a) { if(b) { if (c) { // Do something. } } } Into: if(!a) { } elseif(!b) { } elseif(!c) { } else { // Do something. }

Interestingly I've been going back and forth on this lately. I have been playing around with SD cards on the STM32F4 and a typical SD Card transaction consists of 3 to 10 commands which, if any one fails, the transaction fails. I'm currently using negative conditionals of the form "Not Error" (the Error test is an affirmative, and so that seems ok to me) A typical sequence is like the one to set the bus width. err =…

I actually prefer your second form: return as soon as you know you are done in the function/method -- if nothing more can be done, then don't pretend to do any more.

In the case of cleanup that must be done in the end, perhaps 2 functions would be better: a top level func to acquire and dispose of resources, calling an inner func to do as much work as it can with the resources. (assuming something like C that doesn't have a "finally" clause like Java)

I've never understood how finding the end of a long / nested mess of if/else blocks, rather than leaving the function, is somehow better. Which one feels more like a GOTO in terms of least astonishment?

Re: Clearer Conditionals using De Morgan's Laws

#60
post #19

Earlier quoted context omitted.

Except where writing negative conditionals are clearer. For example turning: if(a) { if(b) { if (c) { // Do something. } } } Into: if(!a) { } elseif(!b) { } elseif(!c) { } else { // Do something. }

Or if (a && b && c) { // Do something. }

iirc, robotics commonly uses something similar called ladder logic.
Post reply on HN