[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