• Naomi (unregistered)

    There's so much about this code style that annoys me. The condition could be rewritten to ... != ... || != ..., which is so much easier to read. StringUtils.equals is either equivalent to Objects.equals (i.e. just a null-safe equality check), in which case it's redundant, or it's not, in which case it's confusingly named. getParameter feels vague and cryptic, but it might be meaningful in context. And then there's the empty else block, of course.

  • Prime Mover (unregistered)

    I once found this paradigm throughout a Fortran app I was maintaining:

          IF ( SOME_CONDITION ) THEN
             SOME_CONDITION = .FALSE.
          ELSE
             CONTINUE
          END IF
    
  • Prime Mover (unregistered) in reply to Prime Mover

    IIRC it inspired a song which went (to the tune of Lili Marlene:

    "Else Continue Endif, that's the code to use

    Else Continue Endif, be sure it won't confuse"

    and I misremember the rest.

  • (nodebb) in reply to Prime Mover

    Was it intentional on your part that the entire code snippet could be replaced with

    SOME_CONDITION = .FALSE.
    

    (note, I'm assuming Fortran booleans don't have .FILE_NOT_FOUND.)

  • Hasseman (unregistered)

    Good old FORTRAN IV with IF but o ELSE. Had to simulate with GOTO's These where the days ...

  • RLB (unregistered) in reply to Hasseman

    Good old FORTRAN IV with IF but o ELSE. Had to simulate with GOTO's These where the days ...

    That was acceptable in FORTRAN IV 1957. Not so much in Sinclair and C64 BASICs in the early 1980s...

  • cschneid (unregistered)

    In COBOL a common rule was only test for positive conditions.

    IF MONTANA CONTINUE ELSE PERFORM 8010-RETURN END-IF
  • (nodebb)

    Does anyone else here ever leave the "if" part blank and only use the else when the negation is too darn hard to read? I have done it a couple of times in my career and it feels dirty.

  • Prime Mover (unregistered) in reply to Jeremy Pereira

    Yes, that is indeed where we are going with this.

    I believe the thinking was that by testing whether the field was false or not first, you would then save wasting vital clock cycles on performing an unnecessary boolean assignment, and ... oh, wait ...

  • ooOOooGa (unregistered) in reply to TheGreatLobachevsky

    Usually I try DeMorgan's rule first. In this case:

    if ((tf.getType() != matchingTimeframe.getType() || !StringUtils.equals(tf.getParameter(), matchingTimeframe.getParameter()))) {

    And if I don't need short-circuit evaluation, use temporary variables.

    if (mismatchedType || unequalParameter) {

  • my name is missing (unregistered)

    If code is good then great, else goto DAILYWTF.

  • (nodebb) in reply to TheGreatLobachevsky

    I have been tempted to do that a few times, but it feels dirty indeed. Usually it is an indication that one should rewrite the condition in such a way that it is both readable and positive (as in handled by the IF part). And it that fails, write the condition as you would, and put a NOT in front of it.

  • Frank Wilhoit (unregistered)

    Long ago -- regrettably, not in a galaxy far away, but right here in this one -- there was a lightweight-database-oriented programming-for-nonprogrammers thingy called FilePro (or, on a different platform, for trademark reasons, ProFile). Every statement was an if/else. If you didn't need the else, you left it empty; if you didn't need the if -- that is, if your statement was unconditional -- you put it in the else.

  • Panda (unregistered)

    Ever heard of MISRA C ? It's a C programming standard, very common in at least the automotive industry, that essentially requires this! (I believe the rationale is "I have considered the other case", but people I've spoken to are vocal that it's not useful most of the time.)

  • I dunno LOL ¯\(°_o)/¯ (unregistered)

    Sometimes I'll flip a condition around to put the shorter exceptional case that ends with a return or break into the 'if' part, to get it out of the way first.

  • Conradus (unregistered) in reply to Hasseman

    How about FORTRAN II, when you didn't have a logical IF at all. Only the arithmetic IF.

  • SD (unregistered) in reply to RLB

    I think MS left out the ELSE in Commodore BASIC to make it fit in the 8 kB available. Otherwise there is no excuse.

    Did Apple, Atari, Tandy, Sinclair, Coleco, TI, etc. have ELSE at the same time? Which of those were also MS BASICs?

  • Well (unregistered) in reply to Conradus

    How about FORTRAN 0, where you had to physically solder transistors in NAND patterns.

  • (nodebb) in reply to nerd4sale

    It is usually because it is implementing a requirement verbatim. The people writing requirements aren't always the most tech-savvy and if it makes the casual source-code reader compare it to a requirement, it stays as is.

    Dear lord, don't get me started on the number of requirements that says if x < y do (foo) else if x > y do (bar) else if x=y do (foobar) where x and y are floating point numbers based on physical attributes (think level of gallons in a 10k gallon tank or flowrate through a pipe).

    Took months of letters going back and forth arguing why they'll never get a meaningful exact comparison (not just floating point epsilon but sensor accuracy) and why it provides no increase in value to break out the exact equality (except $$$ value of the contract since it overcomplicates the test plan.)

  • John Fat (unregistered)

    This is a good practice - it tells the reader that even though this language is not Rust and therefore there are lots of ways you can unintentionally leave a variable null or not handle an error or what-have-you, you have in fact thought through what the impact of the if condition not being true is and <insert impact>, which here is 'no impact'. Very important when you have nested if statements, and certain corporations have it as one of their required style guidelines that every if must have an else and empty elses must be commented.

  • Anon (unregistered)

    I actually have worked in places where this was mandatory as part of the style guide. Similarly, I think some compilers will warn you by default if you don't include a default case in a switch statement. This is also mandatory in Haskell, but that's a very different language in a very different paradigm.

    I think I can see the logic, in a sort of perverse way, even if I don't like it. In Haskell this is done because every statement always has to evaluate to something, and adding some kind of "default" value just doesn't work with the way the language is designed. In this case, and the "default switch" case, the intent is to be explicit about covering every single case, and being explicit that you don't want to do anything.

    I actually hate that condition way more...

  • my name (unregistered)

    I actually worked on a big java 6 project migrated from another language (automagically then "fixed" manually). We started to add else everywhere because we could not figure out whether the else was missing or if it was effectively not necessary. There were lots of other issues (like some files of 20k+ lines, methods of hundreds of lines of code, no tests…) so this thing actually simplify understanding in this context.

  • Foo AKA Fooo (unregistered) in reply to TheGreatLobachevsky

    Only when followed by a series of else-if, e.g. (hope I get the formatting right):

    if (foo)
      { }
    else if (bar)
      {
        // code
      }
    else if (baz)
      {
        // code
      }
    

    Inverting the frist condition (as I normally would) would require an extra level of indentation for the rest, so in this case, it looks nicer to me this way.

  • sudgy (unregistered) in reply to TheGreatLobachevsky

    I once knew someone who wrote EVERY if statement with a negation, no matter how simple, as an empty if branch with an else branch. He said it made more sense to him.

  • (nodebb)

    I absolutely hate the 'one return per function'. It's a complete misapplication of a rule that was designed to discourage you from using the ability in fortran to specify multiple points for a function to return to in the call to the function. Seriously, you'd end up with absolutely no idea where the code might be going.

    There are situations in languages more modern than fortran 2 where it might make your code clearer to have only exit point, but there are situations where it most definitely doesn't.

    It's basically a Cargo cult rule now

    Addendum 2022-03-28 15:54: It's part of the 'single entry, single exit' rule for writing maintainable fortran. Not only did fortran allow return to multiple places, it allowed routines to have multiple entry points. The single entry part of the rule has died because you can't do that any more.

  • MT Hacker (unregistered) in reply to thosrtanner

    re: "it allowed routines to have multiple entry points" An old-school definition of an object (as in OOP) is that they are "modules with multiple entry points and persistent state," so that capability still exists, albeit well hidden behind methods and properties now.

  • MaxiTB (unregistered)

    Ha, another example where someone read Clean Code but didn't understand a thing.

    First, the else statement is basically covered by the rule of not having fall-throughs ever. A good example is the switch statement, but it can also expanded to the else statement. I don't actually remember the reasoning behind it, it never made really sense to me, but eh.

    Second, not using != as an operator again is about the rule of not using negative conditional statements, because they are harder to understand. Personally I also never had any troubles with those as long is it doesn't go crazy with nested double negatives or worse.

    So yeah, this looks to me like code from a complete rookie developer strictly going by textbook with the brain turned off.

  • eric bloedow (unregistered)

    reminds me of a VERY old story where someone insisted on doing "if (do NOTHING) else (do something important) EVERY time he used "if"!

  • Old Timer (unregistered)

    "Only one return from a function" originally and most importantly meant that a (machine code or assembly language) function should only return to where it came from.

    In assembly or machine code, it's really easy to make each exit point from a function go to a different place. It's not obvious in stack-oriented languages, and not obvious when you are using a processor specifically designed for a stack-oriented language, but when your "language" is a macro assembler (like FORTRAN ZERO), and other early environments, why would you want to waste cycles by always exiting with the same exit code to the same entry point?

    The restriction was adopted by early 'structured' languages, where 'structures' like loops and function calls were provided by the compiler: a structure is provided for function calls, but the structure has only one exit point: you always go through the epilogue and back to the call point, (or back to the call point and through the epilogue).

  • (nodebb)

    Isn't "single point of exit" also about error and resource handling in languages without exception handling?

    From my understanding, in C it even constitutes a valid use of goto: "If the function returned an error code, jump to the cleanup section of the function."

    As for the original example of the article: I have come to hate if statements. When you see if CONDITION, you have to guess if there will be an else. I may at some points have done something like

    if(.not. COND) then
        continue
    else
        ! actual logic
    end if
    

    though I'm pretty sure it added some year in purgatory.

    My personal preference would be for all languages to:

    • Require the else on an if
    • Provide when and unless to communicate conditional execution without an else.
  • Kythyria (unregistered)

    A slightly more reasonable reason for "always have an else": dangling elses. This is a syntactic ambiguity: in if(a) if(b) c(); else d(); it's not clear to which if the else belongs (the grammar may specify, but it's still very hard to read).

    Most programmers adopt the more sensible style rule of "always put braces around the body of an if" (or use a language where they're mandatory), but this is the sort of stupid rule that someone will inevitably use instead.

  • (nodebb)

    Always tradeoff's -- how would you set a breakpoint in the code when the condition is not true without the else???? [and yes, sometimes you want to break if the condition is not met]

  • RLB (unregistered) in reply to SD

    I think MS left out the ELSE in Commodore BASIC to make it fit in the 8 kB available. Otherwise there is no excuse.

    Did Apple, Atari, Tandy, Sinclair, Coleco, TI, etc. have ELSE at the same time? Which of those were also MS BASICs?

    Sinclair Spectrum and earlier, no. Not MS. Sinclair Superbasic for the QL, yes. But that was (and had the space to be) a much better language. Also not MS. BBC, yes; also not MS. The rest, I have no idea, except that Apple Basic was MS, but I never used it or any of the others.

  • (nodebb) in reply to Conradus

    How about FORTRAN II, when you didn't have a logical IF at all. Only the arithmetic IF.

    Just simulate it by using computed GOTOs. Assuming you have the usual conventions for 0 and 1 for truth values, it's not too difficult to write a computed GOTO that doesn't drive you completely mad. Really really ugly though, and we try to avoid that sort of thing now precisely because it is really awful.

    OK, merely thinking of computed GOTO is strongly towards madness.

  • Conradus (unregistered) in reply to dkf

    "OK, merely thinking of computed GOTO is strongly towards madness."

    Let's not even mention assigned GOTOs, which seem to have been designed solely for the purpose of making code completely unmaintainable.

  • Old Timer (unregistered)
    Comment held for moderation.
  • nunya business (unregistered)
    Comment held for moderation.

Leave a comment on “If We're Good, Or Else”

Log In or post as a guest

Replying to comment #:

« Return to Article