[Lazarus] 'with' is evil, isn't it?

Michael Van Canneyt michael at freepascal.org
Wed Aug 3 17:15:19 CEST 2011



On Wed, 3 Aug 2011, Max Vlasov wrote:

> 
> 
> On Wed, Aug 3, 2011 at 3:34 PM, Michael Van Canneyt <michael at freepascal.org> wrote:
>
>       On Wed, 3 Aug 2011, Alexander Klenin wrote:
>
>             I also use 'with' extensively, despite the risks,
>             since with the right usage the readablity gains are considerable.
>
>             2011/8/3 Max Vlasov <max.vlasov at gmail.com>:
>                   1. Introducing a check in the compiler setting (or a conditional define)
>                   that could force the developer to use self inside 'with' constructions.
>
>             ...
>                   2. Some switch (maybe on by default) that prevents from compiling if there
>                   are several duplicate names in the same 'with' context (including global,
>                   local, fields).
> 
>
>             Error is IMHO too severe. I think a warning if the name inside of
>             'with' overrides a name from outer scope
>             would be an acceptable compromise.
>
>             Of course, a disambiguation facility would be even better,
>             but I am afraid FPC developers will resist this improvement :(
> 
> 
> Frankly, I don't understand the discussion.
> I use 'with' all the time because it increases readability and reduces typing.
> I don't want to be punished with heaps of warnings simply because I use a language feature. Yes, I am aware that there are risks involved.
> 
> If you don't like 'with', then don't use it, end of story.
> 
> Introducing the proposed switch is nonsense, since it is useful only when dealing with other people's code. For your own code, you don't need this
> switch. Simply don't use 'with', and you're safe. If you type 'with' anyway, that would be very inconsequent of you.
> 
> 
> Michael, one example from Sql
> if you write something like
> 
> SELECT * FROM Detail LEFT JOIN Master on Detail.masterid=master.id where id=34
> 
> sqlite and mysql, probably other dbms will stop you with 'ambiguous column name' error,

Huh ? Firebird does not, and they should not.

It's clear from the statement that id is part of table 'master'. 
If both tables contain a field 'id', only then they must give an error.

I assume you meant to write:

SELECT * FROM Detail LEFT JOIN Master on Detail.id=master.id where id=34

In which case the error is real.

But the analogy is flawed. In pascal, there is a clearly defined scope.
Inside a WITH, the compiler will first search the scope attached to the identifier in with.

SQL has no scope.


> The developers of these dbms could end up with some default way of context resolving (for example the last mentioned table in the sentence), but they did
> not. So many developers feel safer about the fact that if their detail table will get some field with the same name as one of master's, the dbms won't
> silently choose some field. I suppose this requirement could be even the part of SQL-92. Talking about standards, I also admit that Wirth probably never
> mentioned anything about the disambiguation resolving. But we also can be sure that there was no objects and classes when he worked with pascal so there
> were not much of a hidden context in the pascal sources.
> 
> By the way, there's the objfpc mode and it doesn't allow parameters have the same names as field names. This is different to Delphi and generally speaking I
> think this requirement lays in the same area as 'with' disambiguation if implemented. Both serve more or less the same goal, don't they?

They do, I agree on that.

Like I said, there is a 'risk' when using with, I know this. 
But I think it is very small indeed.
(in fact, last week I had such an error after refactoring code, 
but it was the first time in maybe 10 years)

I just don't think that the solutions presented will make it any better.
Say you introduce a switch that forces you to use 'With'.
Then what ?

You'll have to check all 'with' statements because suddenly they no longer compile.
I doubt this will make you find the bug. 
In the worst case, you'll end up prefixing the wrong properties with 'self'.

Michael.




More information about the Lazarus mailing list