1. 11
  1. 14

    TL;DW: Avoid putting if blocks in many places inside a function. Instead:

    1. Use preconditions at the start of the function (if(!thing) return ...).
    2. Use switch blocks to handle all possible cases, assuming your language doesn’t compile when you’re missing cases.

    I lied about the second point. The presenter instead argues for polymorphism, which is more bug-prone than anything (the third point exists to avoid polymorphism-specific bugs).

    1. 2

      The same effect can be had using polymorphism and abstract methods, where the language supports compile-time detection abstract. That works better than switch in many cases IMO, but not all. Most importantly, polymorphism and abstract groups implementations by category in the source, while switch groups them by action.

      I looked at some client code now that issues nine types of server requests. Each request can fail in two ways, can succeed, and can become unnecessary. Using abstract methods mean that each of the nine request subclasses has to implement both kinds of failure or else the compiler will stop everything, and that the implementations for the two kinds are together.

    2. 4

      The presenter argues that coupling between distributed if conditions in the program, that are (or should be) testing for the same, is the killer.

      The argument goes that if you have the equivalent of if(condition1) logically codified multiple places in the program, and you need to change it one place, it is too easy to forget that there are other places. Or (as in the example of adding a null pointer value), merely adding that first innocent if(condition1) really is (the seed of) all those bugs that surface later in all those other places, because the same condition must now be handled there as well.

      Remedies presented include:

      • Compile-time checks, such as with types or switches
      • Centralize each decision, such as by polymorphism
      1. 2

        This looks interesting, but I don’t have 90 minutes right now. I got to the part where he talks about programs being dynamic + temporal rather than static + spatial – could someone summarize the argument against ‘if’?

        1. 4

          He mainly argues against ‘if’ statements that have been put in place to guard against a value that was entered into a function which caused the bug. If a function higher up in the call stack also has a condition that does a similar check, these two ‘if’ statements are now connected. This is a ‘wormhole if’.

          This means that if you are changing code, you might have an undesired effect somewhere else if you do not know that there is an ‘if’ somewhere else that checks similar conditions.

          1. 2

            IMO, the title is intentionally click-baity.

            My take is that he’s mainly arguing against a specific case of if: The repeated if.

            When you’re constantly checking for the same condition in different places, you’re asking for bugs. I think a common example (although not the only one by any means!) is feature flags.

            Rather than if featureX == true 50 times in your code, find some way to control that condition in fewer places (ideally exactly one). A constructor function can be a good place, depending on your language/architecture.

            Large “if trees” are also often cases where conditions are repeated (and what I think @kiwec is responding to in his comments), and refactoring those (i.e. with preconditions and early returns) can also reduce bugs.