Wednesday, August 11, 2004

Why the with-statement should not be extended

N. Ismail commented on my last post about the with-statement:

"I recommend the with statement be extended to allow it to also be written as such:

with a: Form1 do 
begin
a.foo := 123;
a.bar := 'xyz';
a.Caption := 'Test';
Caption := 'Foo Bar'; //The forms caption
end;"

IMO, the with statement should not be extended.


Here are my reasons:


#1. This will help nothing for existing code. Existing code uses with the old way, so the compiler would have to support that syntax for foreseeable future.


#2. Enhancing the with-statement will encourage increased use of it, which is a bad thing, IMO. My suggested warning should encourage decreased use.


#3. What you want can easiliy be obtained today and work in all versions of Delphi. Just define the identifier as a local var and get rid of the with, like this:

var 
a: TForm1;
begin
a := Form1;
a.foo := 123;
a.bar := 'xyz';
a.Caption := 'Test';
Caption := 'Foo Bar'; //The forms caption
end;

"Obviously one could have declared a variable named 'a' of same type as Form1,"
Exactly ;)
"but I think the above syntax is cleaner"

I don't. And it doesn't give you anything functionally that a local variable cannot give you. Its pure syntactic sugar (with a sour taste, IMO).

6 comments:

Deepak Shenoy said...

You know what - the only pain it eases is the var declaration. I think if we had a way to declare a variable someplace within code - like:
begin
...
var a : TForm1 = TForm1.Create;
...

a.Free;
end;

that would work and avoid the terrible "with" statement. I have had so many issues with "with" that I hate using it for more than five lines of code now :) Also there's teh With a, b, c do....or even worse:

with query1, query2 do
Active := True;

Shawn Oster said...

I've always been amazed that VB has a *much* better with implimentation than Delphi. I never use with in Delphi but did find it useful in VB with this syntax:

var
NewClientSupportForm: TSupportForm;
begin
with NewClientSupportForm do
begin
.Caption := 'Monkey';
.Width := 100;
.Height := 200;
if .ShowModal = mrOk then
DanceMonkeyDance;
.Free;
end;
end;

The compiler no longer has to guess what you mean, there are no scoping issues, there is no confusion, it works well for those that enjoy one-off objects.

unused said...

I had some comments about the original post, but I also wanted to comment on the first comment by Deepak. I've always wanted to have the abilit to assign a variable at declaration like most other langauges support, but I am confused by your syntax:
___________________

begin
...
var a : TForm1 = TForm1.Create;
...

a.Free;
end;
__________________

You want to declare the variable within the begin/end block?

Deepak Shenoy said...

Jim,

I'd suggested that to make it easier for the compiler to figure out when a var declaration began - unlike C, where the type comes first, in Delphi the type is "suffixed", so it makes it difficult for a compiler to differentiate a type declaration from a regular statement. Therefore the 'var' keyword. Also this means the 'var' within the 'begin-end' can only declare a single variable (unlike allowing multiple statements when in a section of it's own - that should continue to exist of course) Again, this is only my suggestion: i have no idea what it would take :)

Chris Dickerson said...

The with statement needs to disappear. I would add, there should also be a warning message for empty try/finally blocks.

Jon said...

And an outright error for an empty except...end block. I can't believe the number of times I see errors swallowed like this.



Copyright © 2004-2007 by Hallvard Vassbotn