Recent

Author Topic: How do 'with' statements actually work?  (Read 966 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 19278
  • Glad to be alive.
Re: How do 'with' statements actually work?
« Reply #15 on: May 09, 2026, 07:02:25 am »
So basically work has been done on it but there are still issues?
The Delphi vs Lazarus issue can be explained because of the different inheritance paths, where some properties have a different root, i.e. first appear in different ancestors.
I don't know if that needs "fixing" since the root cause is the wrong visibility.
Garbage in, garbage out, which has always been a risk when using "with": if you are not aware of the scope, things not only can go wrong but will go wrong.

To me it looks like the compiler has been fixed and the remaining issue seems in Lazarus sources. But then again, that seems like I described above and I wonder if that needs "fixing" too.
I mean: if there are different codepaths from Delphi, and there are, there is also different scope, so that is a design issue.
I would not fix that if the scoping is otherwise correct. Use "with" at your own peril. If you can't see the scope, don't use it.

@Handoko might find that his code will no longer work in newer versions of the compiler.....
« Last Edit: May 09, 2026, 07:13:31 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

LeP

  • Sr. Member
  • ****
  • Posts: 348
Re: How do 'with' statements actually work?
« Reply #16 on: May 09, 2026, 10:30:31 am »
If the event is catched by TForm1 and fired while the sender is MyCustomControl then the explanation is simple.
In Lazarus, the event is raised correctly... the code with the "with" expects the event to actually be matched to the custom control (even though it shouldn't be), and the event is matched to the custom control.
In Delphi, however, it's worse: the event isn't matched to the custom control (because, rightly, the with doesn't see it) and is matched to a "random" control (the compiler's rule for choosing the assignment chain is unknown) in the Form1 example.

So, even though Lazarus exposes itself to a missing visibility limit, the behavior is what the programmer would expect.
In Delphi, however, the event is matched to a "random" control, and this is probably worse (although, as @Remy explained, it might be the logically most correct behavior).

I agree with @Thaddy, modifying FPC's behavior could make the situation worse.
Un Sistema per domarli, un IDE per trovarli, un codice per ghermirli e nel framework incatenarli.
An operating system to tame them, an IDE to find them, a code to catch them and in the framework chain them.

VisualLab

  • Hero Member
  • *****
  • Posts: 742
Re: How do 'with' statements actually work?
« Reply #17 on: May 09, 2026, 02:25:10 pm »
A temporary solution would be for the compiler to display a warning to the programmer when the "with" statement interacts with a class variable. Ultimately, it would be best to remove the ability to use "with" with classes, as it causes far more problems (and often errors) than it helps. Using "with" is not a Pascal approach, i.e., one where unambiguity, correctness, and clarity are all-important. The "with" instruction is a cheap, tacky, sleight of hand. In its current form it is at least as bad as "goto". Old "excrescences" should be pruned from the language without any sentiment.

I'm curious what this issue looks like in the FPC Unleashed version, which Fibonacci deals with.


Thaddy

  • Hero Member
  • *****
  • Posts: 19278
  • Glad to be alive.
Re: How do 'with' statements actually work?
« Reply #19 on: May 09, 2026, 05:48:50 pm »
I don't see the relevance because this still fails:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.  with label1, label2 do
  4.    font.Color := clRed;
  5. end;
Which one becomes red? I "expect" both?  O:-)
Dead giveaway: not both!!

Isn't it desirable to do both? Because that is what is "asked", even if there are no duplicates....
Tested against a unleashed version from yesterday's pull and trunk (main) from today.

The error, though, is much appreciated but won't show up in this case....

(If my version is too old, I apologize)
Two labels and a button on a form is too easy to provide a compilable example..

There is no sane solution to "with"

Removing "with" is a better proposal.
« Last Edit: May 09, 2026, 06:38:54 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

Warfley

  • Hero Member
  • *****
  • Posts: 2067
Re: How do 'with' statements actually work?
« Reply #20 on: May 10, 2026, 11:23:13 am »
In its current form it is at least as bad as "goto". Old "excrescences" should be pruned from the language without any sentiment.
Well I mean the issue with with is that it was conceived for a solely procedural version of pascal. Where there were no methods with the implicit self scope, no inheritance with bunch of classes sharing the same fields, etc.. Back when with was introduced it was used to access records that had probably single digit number of fields in a context that had maybe 10-20 local and global variables.
Now it's used for classes with in some cases hundreds of fields, inside methods that have access to hundreds of fields and especially with LCL components most of the time inheriting from some shared base class.

Something that was good back then may not be good today, not because the feature itself is good or bad but because the context it is used in has changed

Thaddy

  • Hero Member
  • *****
  • Posts: 19278
  • Glad to be alive.
Re: How do 'with' statements actually work?
« Reply #21 on: May 10, 2026, 01:00:07 pm »
I agree. Let's call it unforeseen syntactical illogic.
My example above is pretty much the same as from a late 1990's curriculum I wrote for Delphi.
But even nowadays it should alert the reader that "with" is something you should not use without giving it some thought. I know from experience that without compiling the example 100% will read it as: both labels should be red. The remaining 0% is cheating. (That is not an exaggeration )
« Last Edit: May 10, 2026, 01:04:49 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

VisualLab

  • Hero Member
  • *****
  • Posts: 742
Re: How do 'with' statements actually work?
« Reply #22 on: May 10, 2026, 09:05:39 pm »
In its current form it is at least as bad as "goto". Old "excrescences" should be pruned from the language without any sentiment.
Well I mean the issue with with is that it was conceived for a solely procedural version of pascal. Where there were no methods with the implicit self scope, no inheritance with bunch of classes sharing the same fields, etc.. Back when with was introduced it was used to access records that had probably single digit number of fields in a context that had maybe 10-20 local and global variables.
Now it's used for classes with in some cases hundreds of fields, inside methods that have access to hundreds of fields and especially with LCL components most of the time inheriting from some shared base class.

Something that was good back then may not be good today, not because the feature itself is good or bad but because the context it is used in has changed

I think so too. Therefore, the "with" statement should be limited to simple records. It should be completely excluded from use with complex records (variant, managed), objects, and classes. And this regardless of how much "lamentation" would arise after this operation.

Warfley

  • Hero Member
  • *****
  • Posts: 2067
Re: How do 'with' statements actually work?
« Reply #23 on: May 10, 2026, 09:13:18 pm »
Well I personally like the way Visual Basic solved this issue, by introducing a . like this:
Code: Pascal  [Select][+][-]
  1. With MyObject
  2.   .Member = 42
  3.   .Func(42);
  4. End;
Because of the . there is no ambiguity. Of course this still is a problem with nested with statements and stuff like that. Also with is just syntactic sugar for not wanting to type as much. Maybe this was an issue when space was limited as well as tooling wasn't that great, but with autocomplete and hell even AI assistants today, there is no need to save those few words.

What I like about with is the scoping, e.g. something like this:
Code: Pascal  [Select][+][-]
  1. With TSomeClass.Create do
  2. try
  3.   ...
  4. finally
  5.   Free;
  6. end;
It avoids creating a temporary variable that may clutter the function definition. But then a solution like Pythons with statement, which also enforces lifetime would be more appropriate:
Code: Pascal  [Select][+][-]
  1. with open('Filename') as fl do
  2.   fl.Write('Hello World');

Generally speaking there have been some iterations on with with more interesting ideas on how to evolve this feature. The most telling thing is that in JavaScript with, which works exactly like in Pascal, was completely deprecated because it is "too dangerous" due to the shadowing of identifiers.

Nicole

  • Hero Member
  • *****
  • Posts: 1324
Re: How do 'with' statements actually work?
« Reply #24 on: May 11, 2026, 04:01:19 pm »
this is somehow off topic:
Years ago an old Delphi-hero says "with brings bad luck".

It took me years to find out, that he is right.

Thaddy

  • Hero Member
  • *****
  • Posts: 19278
  • Glad to be alive.
Re: How do 'with' statements actually work?
« Reply #25 on: May 12, 2026, 09:14:38 am »
What I like about with is the scoping, e.g. something like this:
Code: Pascal  [Select][+][-]
  1. With TSomeClass.Create do
  2. try
  3.   ...
  4. finally
  5.   Free;
  6. end;
In that context, yes, I use that too. Single scope, though. Introducing multiple scope is where it all goes wrong.
objects are fine constructs. You can even initialize them with constructors.

 

TinyPortal © 2005-2018