1

I have the following code:

subroutine foo(int index)
{
    // Check A.
    // Critical: Check A must precede Check B below.
    if (index == 1)
    {
        return true;
    }

    // Check B.
    if (index - 2 < 0)
    {
        return false;
    }

    return true;
}

The code is a simplified representation of a real-life scenario where I am checking for validity of punctuation marks in a string.

My question: Is there a construct in any language which would guarantee that the order of the two if statements are maintained as is? (Without having to place a comment in the code as I have done and hope that it is heeded.)

For the case where index is 1, if Check B is moved before Check A, Check A will never be caught and foo() will always return false, which is bad.

Again, my concern is for the maintenance of the code by future programmers. There are about 10 if statements in the code, one after another, and their order is important.

EDIT 1:

I am an experienced developer, and I am really asking whether there are any new developments in languages that would allow for what I am asking above. I am sorry that I did not make this clear.

EDIT 2:

In response to comments suggesting index < 2 instead of index - 2 < 0: I don't agree. index - 2 indicates that I am interested if there is an item two locations before the current index, while index < 2 does not convey the same information. (Of course, this is my opinion!)

  • 3
    How would you handle the situation where you have gotten the sequence wrong and a maintainer later needs to correct your mistake if the maintainer is not allowed because of the 'language construct' you have used? – Bent Jan 22 '16 at 11:20
  • 2
    No pattern or source code construct can prevent people from editing you code. – JacquesB Jan 22 '16 at 11:25
  • 2
    The easier understandable your code, the lesser the chances of messing around with it. For example, (index < 2) would be much easier to read and understand for me. And in this case, it's the same as (index < 0). Make your logic as easy to follow as possible. – Eiko Jan 22 '16 at 11:27
  • if index <= 0 return false else return true? – Pieter B Jan 22 '16 at 11:33
  • 1
    @MetaFight: Not really, when the alternative is keeping a variable lying around until the last line of the function, to return variable, that you then have to track just as much as you would have had to track the return statements. Meanwhile, you introduce potential bugs by not immediately ending execution of the function when that's logically what you need to happen. – Lightness Races in Orbit Jan 22 '16 at 11:57
9

Anyone who can edit the source code can remove anything that you might put in there to "protect" them. You can do two things:

  1. Choose a good name for the function that conveys your intention

  2. Provide Unit Tests that will break if someone ever changes what the function does

Both do not prevent future programmers from changing anything if they need to, but they will have some guidance in how the function was intended to behave.

Another option would be to turn these temporal dependencies into structural ones by having the first one generate/return something that the second one requires as input. But that is likely overkill for something as simple as your example. Robert C. Martin mentions this technique in his book "Clean Code".

  • 2
    Good point on the unit test! – Eiko Jan 22 '16 at 11:23
  • I do have unit tests. I was looking for something that is part of the language. – Sabuncu Jan 22 '16 at 12:06
  • You mean "The Clean Coder"; I have that book, but could not locate the reference just by skimming the content. Will look into it though, thank you. – Sabuncu Jan 22 '16 at 13:17
  • @Sabuncu No, that's actually a different book by the same author – Hulk Jan 22 '16 at 13:25
  • Thank you! You are right, it's a different one published in 2009. Page 303: "Each function produces a result that the next function needs, so there is no reasonable way to call them out of order." Under the topic "Hidden Temporal Couplings". Much appreciated. – Sabuncu Jan 22 '16 at 13:33
4

In probably all relevant languages, the statements are processed in order.

And that's valid for the whole program code. Even the simplest programs wouldn't work otherwise.

If someone is allowed to change the code but doesn't understand anything about it, there's not much you can do about it, except removing his rights to do so.

Nothing wrong with a comment in the code if it is hard to understand, or refactoring the code to make its intents more clear, of course.

Edit (as in comment):

The easier understandable your code, the lesser the chances of messing around with it. For example, (index < 2) would be much easier to read and understand for me. And in this case, it's the same as (index < 0). So this function always returns true for positive numbers, so the whole function is as simple as return index > 0.

Make your logic as easy to follow as possible.

And - as another answer has pointed out - this should be captured by a unit test anyway.

2

So, you're asking how to protect your code from clumsy future devs? That's a tough task which is usually handled by applying code organisation techniques and not language constructs.

In this specific case, I would simply make sure that reorderring the if blocks didn't functionally change my method. Like this:

subroutine foo(int index)
{
    bool checkA = (index == 1);
    bool checkB = (index - 2 < 0);

    if (checkA)
    {
        return true;
    }

    if (!checkA && checkB)
    {
        return false;
    }

    return true;
}

Of course, you could accomplish the same thing by putting CheckB in CheckA's else block, but then we're nesting ifs, which I don't like.

  • This is a good approach. checkB will be needlessly evaluated, but that bool assignment can be moved into the condition for the second if statement, and then used for check C, and so forth. The cascading checks in the if statements would clue the "future clumsy devs" that order is important. Thank you. – Sabuncu Jan 22 '16 at 12:17
  • I meant checkB would be needlessly evaluated if checkA is true. – Sabuncu Jan 22 '16 at 12:26
  • 1
    evaluating checkB adds negligible overhead. It shouldn't a factor in your decision making at all unless you're developing in a constrained environment. Don't fall into the trap of premature optimization. – MetaFight Jan 22 '16 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.