Friday, April 24, 2009

Use positive expressions

When striving for clear and concise articulation, in programming or in natural languages, try to express yourself with as few negations as possible. Negations leed to confusion. Our brain does not handle them well.

Example 1: It is better to ask "may I sit here?" than "is this seat taken?". Try it. The latter question will confuse some people. They might answer "no" even though the seat is taken and vice versa, especially if you mumble and all they understand is your intention to take that seat. Their brain translates the question to "should I allow the guy to take that seat?".

Example 2: if a newspaper writes "Senator Smith never smoked pot", the number of people thinking that Senator Smith smoked pot might grow because all they might remember is "senator smith" and "pot". Negative associations rarely work.

When programming, it is essential to write clear and understandable code. Avoiding the not operator helps.
  • It is better to write "if x==7 then a else b" than "if x!=7 then b else a".
  • It is also better to create a method "list.hasItems" than "list.isEmpty".
  • It is better to have a checkbox that says "cache thumbnails" and is enabled by default than a checkbox "do not cache thumbnails" that is disabled by default (as found in the folder options of Windows).
You get the idea. Internalize it.

15 comments:

  1. hi

    i'm not sure i agree with your examples. For me list.isEmpty is not a negative statement. That would be !list.isEmpty.

    when doing if / else's i often like to have the smallest block first, so that would influence the condition being chosen.

    I never noticed being confused by a condition being positive or negative.

    but now that i've read your post, maybe i will :)

    gooddday,
    nico

    ReplyDelete
  2. This is a really good point.
    "do you mind if I....?" always leaves me confused because I know that whether I answer 'yes' or 'no' the person asking the question will still be confused as to what I mean.

    This usually lead to a longer answer such as "Yes, I'd rather you didn't"", or "No, I don't mind"

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. I'm not sure about the message you want to convey using real-life examples but as a programmer if I am supposed to review someone else's code , I prefer the use of conditions to be

    " if true then action "

    rather than

    "if false than action"

    This kind of logic thinking is already programmed in our brain which happens with most of our everyday decisions . So it makes me read the code easily rather than putting some extra effort on the conditional expressions . So obviously use of positive expressions in any statement helps to express yourself better.

    ReplyDelete
  5. I agree completely, negatives confuse me.

    However I think isEmpty is a concept on it's own rather than a negative concept. I'd suggest using both isEmpty and hasItems rather than negating either.

    ReplyDelete
  6. Do you not think this was useful?

    ReplyDelete
  7. I think that isEmpty is fine.
    In my opinion, code reads better if it first rules out some edge cases (an empty list, a null argument etc.) and then does the 'main' work, unobscured by the edge cases at all.

    Using hasEmpty would make the edge case use negation, the code would look like

    if(!list.hasItems()) return foo;
    return mainWork();

    ReplyDelete
  8. @jkff: I'd structure the code as:

    if (list.hasItems()){
    doWork();
    }

    This is IMO more readable than

    if (list.isEmpty()){
    return;
    }
    doWork();

    ReplyDelete
  9. I see where you're coming from, but when you say "It is better to write 'if x==7 then a else b" than "if x!=7 then b else a'", I think it's definitely better to write what makes the most sense in the context, rather than having some general rule.

    For instance, if you're testing for an admin being logged in, I want the code to scream to me that under normal circumstances the admin code should not execute, (i.e. the 'default'/safe behavior is when the admin is NOT logged in). So in ruby I'd say "unless user.admin?..."; having unless there, to me, seems like the code is generalized for the safer situation (not admin) and there's a very limited scope where that admin block would execute. If I switched the if and else around and went with 'if user.admin?', yes that first block is very specific in it's scope, but the safer behavior ends up in the 'else', and then you have to infer, 'ok, this code is running when the what was specified up there ISN'T happening', rather than that safe behavior being explicitly defined in the code.

    ReplyDelete
  10. misspellings leed to confusion.

    ReplyDelete
  11. I agree with Farski on this. My general rule of what condition to place in the if side of an if/else is the "normal" or "expected" route. The classic example of this is null checks.. Since a null is typically unexpected, I want to put the normal case of !null first, so that the code will tend to flow in the expected-case first. I also tend to stay away from nullcheck-throw or nullcheck-return type statements ahead of the !null code, as it makes breakpoint debugging a real bizzatch.

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. I am not a programmar but I totally agree with you. Hongjoo from Korea, googled your article while trying to start a private column. It really is a small world. If you ever have a chance to visit Korea send me a mail. Who knows? I could be a big help.
    hjleehj@naver.com.

    ReplyDelete