When You Say Nothing At All…

This is another one of those posts that has a bit of a double meaning in the same title. First, there is the matter of a useful hint/warning that I think could be emitted by a Pascal compiler. The other is what I have been up to in recent months that I have been so busy that I wasn’t posting much (i.e. at all) !

First the more relevant point to this blog:

When you say nothing at all, in Pascal

Consider this very simple piece of code:

  if SomeCondition then
    i := 42
  else
    i := -1;

Nothing controversial here, obviously (and just as obviously, this isn’t real code; it’s just for illustration). Where SomeCondition is TRUE, i takes the value 42, otherwise it takes the value -1. Simple. What could possibly go wrong ?

The addition of just one character to this code will silently change the outcome completely, resulting in i always taking the value -1:

  if SomeCondition then
    i := 42
  else;
    i := -1;

Do you see it ?

Of course, it’s going to be much easier to spot in an isolated example like this, but imagine reading this amongst the background noise of real world application code and you should appreciate how much harder it could be to identify in practice.

The problem is of course that little semi-colon that has crept in after the else, completing the if-else with a null statement. What I call a “NO-OP” (NO OPeration).

The if-else now has an empty else clause and is immediately followed by an unconditional assignment of -1 to i. Now in this case you do get a hint that the value (42) assigned to i is never used, but I think a more specific warning about the empty statement would be more useful.

Of course, such empty/null statement NO-OP‘s can be useful. I use them quite often with case statements for example, or anywhere else that I need to demonstrate and self-document that some potential case has been “left intentionally blank” rather than having simply forgotten to deal with the case, but I always document them as such:

  case Status of
    asError   : Color := clRed;
    asWarning : Color := clOrange;
    asOK      : { NO-OP - no color change } ;
  end;

Or an introduced virtual method which is specifically not abstract but which explicitly has no base class implementation. Or in an override which deliberately suppresses the inherited implementation (i.e. does not call inherited and provides no replacement implementation):

  procedure TFoo.OverrideMe;
  begin
    // NO-OP
  end;

You don’t actually need to comment/document your NO-OP’s in this way because they are perfectly valid, but I consider it a useful indication that the NO-OP is a deliberate and considered aspect of the implementation, rather than an accident of oversight or omission.

Which is great when you deliberately introduce these NO-OP’s, but when you do so unintentionally, you get no warning. I think it might be useful to have such a warning, or at least a hint. Of course, this will result in a slew of warnings in existing code which contains perfectly valid, empty statements, and no easy way to deal with those warnings.

Two ways of dealing with this might be:

  1. Introduce a new keyword specifically to indicate a deliberate empty statement. Even without compiler support this could be approximated by simply have a particular named procedure that you call in such cases. This might be preferable anyway given that this would be necessary in code that has to support older compilers which would be unaware of the keyword.
  2. Emit the hint/warning as part of the source parser and allow a comment to be treated as representing a “statement” in such cases. Then as long as an empty statement at least contains some comment (i.e. documentation) it would be considered not requiring a warning.

In the latter case of course the parser has no way of knowing whether any comment in an otherwise empty statement is actually useful documentation for that empty statement or not. So perhaps there should be different levels of strictness that may be applied. i.e. emit hints/warnings for all empty statements or only for only those that do not contain comment(s), to be applied as suits your individual coding standards in such areas.

In any event, any such hint/warning is probably best introduced as disabled/turned off by default.

It’s not a world changing improvement to the language, but it could be a useful one. :)

A Busy Start to the year…

As for my own relative silence in recent months… what can I say ? It’s been a very busy start to the year !

In January my fiancée and I resumed house hunting as we had always intended to do after Christmas, expecting it to take a few months. Within a week we had found a house and one thing followed another and another week later we had a purchase agreement in place !

Then in February we got married. Unlike the house, this had been planned well in advance but still took a great deal of last minute organising, not least due to the logistical challenges arising from our decision to get married in Hokianga, a beautiful location in the Far North of New Zealand but about 4 hours drive from Auckland where we live. Natural beauty aside, Hokianga is a special place for us as it is where we went on our first trip away together.

Hokianga in Maori means “Returning Place”.

Then, the week before the wedding we were invited to a ceremony (along with almost 500 other new citizens!) to receive our certificates of New Zealand Citizenship, to occur just a week after the wedding itself.

My wife’s parents had travelled to New Zealand for the wedding and were staying on for a further month after. Being able to be present at the Citizenship ceremony was an unexpected bonus for them. Also unexpected but unfortunate were the events unfolding for them back home, in Ukraine. If you have been at all aware of events in that region you can appreciate that the joy of the wedding was soon overtaken by concern for what they might have to return home to (last week). They live in Donetsk.

Fortunately it has been a relief for them to find that life in Donetsk is actually far less affected by the goings on there than we had feared might be the case in the former President’s home region. We can only hope that things remain that way and that the situation is soon resolved.

One additional complication arising from the wedding came from our decision to blend our names. Had either of us taken the other’s name this could have been achieved simply by making that change on the marriage certificate. But since we were both taking a new name we instead had to apply for a legal name change, separately.

That took effect last week, so I am now legally “Jolyon Direnko-Smith“.

And last but not least (as if all that wasn’t enough to be dealing with!) I decided to move on from my job at Flow Software. I am currently “between jobs”, waiting to take up a new post at Datacom, next week.

So, all in all, very exciting and very busy times. :)

And that’s without even mentioning the release of AppMethod and RemObjects Elements with a major new release of Oxygene and an exciting new direction for C# !

A couple of commenters have mentioned these developments already and I of course expect to be blogging about these in the near future, now that the world is spinning at a (slightly) more manageable rate ! :)

Tags: , , ,

20 comments

  1. David Cornelius’s avatar

    Congrats on marriage, house, job, and citizenship! Wow–no wonder you’ve been quiet here.

    A comment about your topic: Yes, I agree there should be a warning about else clauses without a statement. In fact, I would argue that it should even be an error–why would there be an else if there’s no statement to execute?

    On the other hand, with good software practices in place, unit tests would quickly reveal the flaw!

    1. Deltics’s avatar

      Thanks. :)

      The error was indeed spotted very quickly. :) And yes, the “else” scenario is the most obvious example of an accidental omission, but there are plenty of other examples where an accidentally empty statement would not be so obviously wrong (and may actually be intentional).

    2. William’s avatar

      I have been changing my style after reading more and more articles about defensive programming… My style of your example should be something likes:

      if SomeCondition then begin
      i := 42;
      end else begin
      i := -1;
      end;

      So an empty if then else should looks like:

      if SomeCondition then begin
      { place holder }
      end else begin
      { place holder }
      end;

      A few more key stokes are needed, but save my own time in the long run!

      1. Deltics’s avatar

        This isn’t a perfect defence in this case. Whilst it protects against a semi-colon creeping in at an end of line after a begin

        if SomeCondition then begin
        { place holder }
        end else begin;        // compilation will fail
        { place holder }
        end;
        

        … since it is perfectly legal to have a compound statement (begin-end) exist in “isolation” it doesn’t help if the semi-colon still somehow manages to creep in unnoticed after the else

        if SomeCondition then begin
        { place holder }
        end else; begin         // Still silently creates an empty statement - perhaps even harder to spot
        { place holder }
        end;
        

        Although this sort of end-of-line error is perhaps more likely with a different approach to begin/end formatting:

        if SomeCondition then
        begin
          { place holder }
        end
        else;            // Still silently creates an empty statement
        begin         
        { place holder }
        end;
        
      2. Joseph’s avatar

        Doesn’t the “else” become a lot harder to notice?

      3. Joseph’s avatar

        Jolyon,

        I’d been worried about you and the same night I said to someone that I had to e-mail you to see if you were ok I saw your new post! Glad to hear the things going on in your life are positive.

        To address your syntax issues, you need simply turn to the best version of Pascal ever created: Python. :-)

        The issue with the “if” statement is due to the fact that in Pascal and several other languages the indentation can lie to you (and has been the source of some million-dollar horror stories). Implement significant whitespace and the problem goes away.

        If some_condition:
            i = 42
        else:
            i = -1
        

        There’s no way I can rewrite that statement that will make i accidentally always be assigned -1. It’s always clear what code is in a control block and mistakes are easily spotted. This is what Pascal needs; I know Eric Grange was considering it for DWScript. Your example here is a very good demonstration of why significant whitespace is so useful.

        As for your second issue, Python introduced a statement called “pass” that does nothing. You actually can’t have a completely empty function or class, so

        def OverrideMe:
        pass

        would be the only way to write a function that did nothing.

        I’m sure your best friend David I. has you on speed-dial so feel free to call him up and make these syntax suggestions. ;-)

        What development language will you be using at your new job?

        1. Joseph’s avatar

          Sigh, there should be four spaces before “i = 42″ and “i = -1″. What magic do I have to use to get the nice syntax highlighted code like you have?

          1. Deltics’s avatar

            Cheers Joseph! :)

            w.r.t code formatting, I use the Syntax Highlighter plugin for WordPress with a few tweaks for specific language support (primarily Delphi and Oxygene). For Delphi, enclose code snippets in a “delphi” tag, but using square braces not angle braces:

            *delphi*
            // formatted code here
            */delphi*

            Obviously replacing the ‘*’s with open/close square braces as appropriate. I’ll edit your previous comments to pretty them up. :)

            For less pretty, more generic code formatting, use the tag “code” instead of “delphi” (but again, using square braces rather than angles).

          2. Deltics’s avatar

            Sorry Joseph, I forgot to answer your last question…

            My new role is also a predominantly Delphi role but is of a quite different nature than my previous role.

          3. Sebastian Jänicke’s avatar

            Without begin..end the “pseudo else block” would be formatted without indentation by the code formatter, so it would have been spotted at once.

            With begin..end this is not the case as it is not formatted differently in both cases…

          4. David M’s avatar

            Congratulations! Wedding, house, job, and citizenship, a lot of good life changes in a short amount of time. Out of interest, I gather you live in New Zealand – where were you a citizen of before?

            1. Deltics’s avatar

              Cheers David. :)

              Yes, I emigrated to New Zealand from the UK, way back in 2005. Fortunately I don’t have to give up my British citizenship as both the UK and NZ allow dual citizenship. I am still a citizen of the UK as well as NZ.

              (The oddest part of the NZ citizenship ceremony was swearing an Oath of Allegiance to HM Queen Elizabeth II – seemed a bit redundant since I was already one of her subjects and citizens and thought I was pretty allied already ! :) )

            2. Jørn Einar Angeltveit’s avatar

              I asked about no-op a while ago too :-)

              http://stackoverflow.com/q/7536493/267938

              Some interesting comments…

            3. Jason Sweby’s avatar

              Just for once, I won’t challenge you and just say congratulations instead :)

            4. Scooter Software’s avatar

              Sock Software’s CodeHealer has “empty if” as one of their audits, so it would have picked this up. Certainly better to have it built into the compiler, but it is available if you know where to look. :)

              1. Deltics’s avatar

                Interesting, something to look into. Cheers.

              2. Alister Christie’s avatar

                Congratulations on you marriage, new home and new job, I’ve done pretty much the same thing last year. Purchased a lifestyle (life-sentence?) block in April, changed jobs about the same time and got married on our farm in November. I’ll probably have some extra time this year, so look out for new videos.

                1. Deltics’s avatar

                  Cheers Alister, and congratulations yourself ! :)

                2. Matthew Kinney’s avatar

                  Cheers Jolyon on the marriage and other life changes! I don’t post much but have followed your blog for some time–you have saved my bacon quite a few times.

                  Hope this isn’t too forward but it looks like you did quite well for yourself–something else we have in common besides Delphi and Oxygene :)

                3. Al González’s avatar

                  Hi Jolyon.

                  Your article reminded me of a simple (but useful) function with no code I wrote some time ago. As it is not a virtual method, but a standalone routine, I included in it the respective comment:

                    Function ghWidePtr (Const S :WideString) :Pointer;
                    Asm
                      // NOTE: This function is OK, it has no explicit code.
                    End;
                  

                  Congratulations on your marriage, a concept that I respect and admire, but still do not understand (maybe because I have not been lucky enough to fall in love and be loved by the same woman). :-)

                  Al Gonzalez.

                  P.S. I wish Ukraine stabilizes soon. The world needs more constructive thoughts (such as Delphi programmers often have) and less politicians. :-)

Comments are now closed.