The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,259 other subscribers

WITH IS EVIL! (via: Paul Foster – Google+)

Posted by jpluimers on 2014/03/13

Yet another example of somehow who got bitten hard by using the with statement (I decided to give with its own category on my blog).

This time it got shared by Paul Foster on G+ and comes down to this:

Even in unsuspiciously looking code, the wit statement can bite you, especially if you need to do refactoring and (because of that) introduce two names in the same scope.

Or in Paul‘s words:

Whilst upgrading the code to remove the Containers unit (its not supported on NextGen platforms, so I have to make things work with Generics.Collections instead, (bye bye D7 support for this code) and refactor a couple stupidities in my original design (they always creep in, don’t they) I ended up with two class members of the same name.  The with block then looked OK but I was in fact not access the member I thought I was. 

–jeroen

via: Paul Foster – Google+ – WITH IS EVIL! God damn it, I know it makes code easier to….

18 Responses to “WITH IS EVIL! (via: Paul Foster – Google+)”

  1. Leonardo Herrera said

    I got bitten by _with_ once. Actually, I got bitten _removing_ a with block:

    with recordset do
    begin
    while not eof do
    begin

    next;
    end;
    end;

    When I removed the with block I inadvertently left the “eof” instruction alone. That (to my ulterior surprise) compiles, but fails with a cryptic system error at runtime.

  2. Gerard said

    ” I ended up with two class members of the same name. The with block then looked OK but I was in fact not access the member I thought I was. ”

    There are a lot of ways to stuble about own errors, especially pointers and other pitfalls.
    So using “with” you should know what you are doing, same like pointers etc.

    • jpluimers said

      The thing about “with” is that it can make your code a lot less future proof. A changing in an underlying library can break your code without any compiler hint, warning or error.
      Of course there are unit tests, but they don’t cover everything and lots of things are hard to test.

  3. Delphi mourner said

    It needs to be fixed, that’s all. Most languages have some form of local de-referencing capability. In Delphi, that’s the WITH statement. Many, many, many suggestions have been posted in the Q system over the years, how this could be done. All have been ignored. Dephi is an ageing language. The work needed to bring it up-to-date is just piling up.

  4. Hi Jeroen.

    Yes, the current With is very bad. But It can/must be improved with three simple changes:

    1. No more than one object/record per With header.
    2. Nested Withs not allowed.
    3. Usage of ” to indicate the object/record (double quotes are similar to the ditto mark:
    http://en.wikipedia.org/wiki/Ditto_mark).

    Examples:

    http://rescatandoadelphi.blogspot.com/2014/03/my-proposal-for-better-delphi-with.html

    • jpluimers said

      Like I tweeted before: That change breaks a lot of code. Besides why not use the dot (.) or a local (like try/except does)?

      on using the dot (.): it has been successfully used in VB, and is very readable http://msdn.microsoft.com/en-us/library/wc500chb.aspx

      With theCustomer.Comments
      .Add("First comment.")
      .Add("Second comment.")
      End With

      on try/except: it introduces an inline variable (this time called `E`) http://docwiki.embarcadero.com/RADStudio/XE5/en/Exceptions#Try…except_Statements

      try
      ...
      except
      on E: Exception do ErrorDialog(E.Message, E.HelpContext);
      end;

      • Hi Jeroen.

        The double quotes (“) have three advantages over the dot (.):

        1. They are more legible (I do not think is good idea that our Delphi code contains little isolated dots).
        2. They are more eloquent (many of us have ever used the double quotes or “ditto”/”idem” mark in order to note that some of the text above is repeated).
        3. They are more secure.

        Consider the following code block using dots:

        With TForm1.Create (Nil) Do
        Try
        LogX (Application .Name);
        .ShowModal;
        Finally
        .Free;
        End;

        LogX is a hypothetical outer overloaded method (one and two parameters), the programmer forgot to write the comma between “Application” and “.Name”, and the compiler does not notice it. :-(

        Consider that same code block using double quotation marks:

        With TForm1.Create (Nil) Do
        Try
        LogX (Application “Name);
        “ShowModal;
        Finally
        “Free;
        End;

        LogX is a hypothetical outer overloaded method (one and two parameters), the programmer forgot to write the comma between –Application– and –“Name–, but this time the compiler notices it. :-)

        The programmer adds the comma:

        With TForm1.Create (Nil) Do
        Try
        LogX (Application, “Name);
        “ShowModal;
        Finally
        “Free;
        End;

        Example of “alone” double quotes (the LogForm’s parameter):

        With TForm1.Create (Nil) Do // New TForm1 instance
        Try
        LogForm (“); // That same instance as parameter to an outer method
        “ShowModal; // Instance.ShowModal
        Finally
        “Free; // Instance.Free
        End;

        Regarding the alias usage, I’m not sure that’s a good idea to continue to allow, in Object Pascal, variable declarations in half the code. Unlike With, Try..Except blocks are somewhat special. I even think that they could also use the double quotes. ;-)

        Jeroen, could you fix the second link in my first comment? This should be:
        http://rescatandoadelphi.blogspot.com/2014/03/my-proposal-for-better-delphi-with.html

        Thank you very much. Best regards.

        Al Gonzalez.
        @algonzalez74

        • jpluimers said

          I disagree, but that is OK.

          0. Dot is already a selector operator in the language, so why create another operator for it (this is one of the reasons there is no `foreach` but a `for..in` operator).
          1. Double quotes are used for strings in too many programming languages.
          2. Many people use single quotes for ditto/idem.
          3. With should be much more special than Try.
          4. Delphi should have had localized variables a long time ago as it makes it way easier to adhere to the proximity principle.

      • Hi Jeroen.

        Thank you so much for fix the link. I will try to answer your last arguments.

        0. Dot is already a selector operator […]

        Yes, the dot is a separator or selector, but the double quotation marks are a wildcard. How do you specify the object inside the With statement at Visual Basic?

        1. Double quotes are used for strings in too many programming languages.

        Yes, and many of them C-derived languages. The (Object) Pascal syntax was/is conscientiously constructed. It saddens me a bit to see how the inertia of C continues calving dismal syntax languages.

        2. Many people use single quotes for ditto/idem.

        Maybe we’ll have to do a survey. :-)

        3. With should be much more special than Try.

        Sorry for my imprecise English. In a sense, it is like you say.

        4. Delphi should have had localized variables a long time ago as it makes it way easier to adhere to the proximity principle.

        In that sense, I think the proximity principle must be directly proportional to the healthy habit of writing routines of few lines of code.

        I am glad we agree that the Delphi With statement can or must be improved. I think it is good that together we all find the best way to do it.

        Al Gonzalez.
        @algonzalez74

        • jpluimers said

          How do you specify the object inside the With statement at Visual Basic?

          Using the . select operator (at the same place where you propose “). See the example I gave earlier.

          It has worked there for decades.

      • A lone dot? Where?

        This is the example using a lone wildcard I gave above:

        With TForm1.Create (Nil) Do
        Try
        // That same entire object (” = the TForm1 instance) as parameter to an outer method (LogForm)
        LogForm (“);

        “ShowModal;
        Finally
        “Free;
        End;

        • Leonardo Herrera said

          He says that Visual Basic used the dot inside the with statement (like this: http://stackoverflow.com/a/1168702/7841).

          I’m sorry, but a single, unterminated double quote in code makes me want to scrub my monitor with soap.

        • jpluimers said

          Your proposal requires a lot of work in the compiler, as you introduce a ditto/idem operator that also functions as a select operator.

          Knowing the team, they’d never do that (for the same reason the did not introduce a foreach operator). If you insisted on a ditto operator, you’d get something like this at the most (I’ve reformatted your source code, used the correct double quote, and changed case as your coding convention is terribly different from the default one used in Delphi):

          with TForm1.Create(nil) do
          try
          LogForm (");
          ".ShowModal;
          finally
          ".Free;
          end;

          In my book it would be like this:

          with MyForm: TForm1.Create(nil) do
          try
          LogForm (MyForm);
          MyForm.ShowModal();
          finally
          MyForm.Free();
          end;

          Without the temporary inline variable, you would not be able to call the `LogForm` at all:

          with TForm1.Create(nil) do
          try
          // LogForm (.); // cannot do this as the selector has nothing to select.
          .ShowModal();
          finally
          .Free();
          end;

          Anyway: since they have not changed with despite various proposals in the last 20 years, I doubt even my proposal would be implemented anytime soon. Your more complex proposal has an even lower chance.

          –jeroen

      • Imagine then what would be a tiny lone dot!
        —– LogForm (.); —– :-(

        What matters is to improve the With statement, making it more sure (and complete). There are many other symbols available, which of them do you prefer and why?

        Best regards.

        • jpluimers said

          There is the whole Unicode alphabet full of symbols to use, and I prefer to use no other one.

          The point of Pascal based languages is to limit the number of symbols, operators, keywords and directives as much as possible. That avoids building another APL.

      • Hi Jeroen.

        There is something odd in the order of the messages:

        Leonardo Herrera said
        2014/03/19 at 15:53

        jpluimers said
        2014/03/19 at 21:19 <– After

        Al Gonzalez said
        2014/03/19 at 18:34 <– Before

        My latest question was for Leonardo, but no matter. :-)

        Previously I explained why, for me, the double quotation marks are more suitable than the dot, in order to improve the With statement: legibility, eloquence and security. Those three reasons weigh more when we consider that we could use a "wildcard" symbol for specify the entire object inside of the With statement. I understand the affair of the symbolic languages (these are truly terrible) ​​and the relatively well maintained purity of Pascal. Since I started with Pascal (in 1991), I have known some programmers we could label as "ultraconservative", and know what it is to try to convince them that the Earth rotates.

        However, I think we, the Delphi users, are who must be convinced that the current With is wrong, and that the solution is not to destroy but to improve it. We must continue to propose the "how to" because, as Community Delphi, we are quite capable of bringing down some few prejudices and dogmas. I do not care if my proposal has a lower chance; I am interested that Delphi developers continue to build great solutions without being forced to get rid of their common sense.

        “Daring ideas are like chessmen moved forward. They may be beaten, but they may start a winning game.”
        –Johann Wolfgang von Goethe.

        • jpluimers said

          WordPress does a lot of odd things, including messing up the comment stream (:

          I’m with you that improving the language is worthwhile, but also want to draw a realistic picture about the with statement, operators and such.

Leave a reply to Delphi mourner Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.