I had to change something in some old Borland Pascal program today and I had to restraint myself very forcefully not to start removing with statements. Otherwise I would still sit at work trying to figure out all the bugs that would have occurred afterwards. With statements are evil but nested multi-with statements in object oriented code are the devils own invention:
Procedure TSomeObject.doSomething; Begin With someProperty, someFieldOfThatProperty do begin { ... } With someOtherProperty do begin SomeField := someProperty.SomeField; End; End; End;
Lars Fosdal Can you imagine if Embarcadero snuck in an "ambiguous reference" hint or warning that was generated whenever an identifier inside a with conflicts with an identically named identifier defined outside the with's scope.
It wouldn't be very pascalish though. The same ambiguity exists at the unit, class and function level.
Remember: A Kitten dies each time you use WITH. Don't do it and save a precious life - and the sanity of the poor schmuck that has to maintain your code. :-)
Kenneth Cochran I had to check, but Wirth kept "with" in Modula 2 and Oberon. However in Oberon, it appears that the "guard" cannot be a list, so with a, b do is not supported.
Bill Meyer It is more than offensive. The danger is that it allows changes in unrelated code to cause sudden bugs in it. Offensive in this case is probably the understatement of the century :-D
Bill Meyer Only place where 'with' doesn't pose any real danger are standalone functions and procedures that operate on records.
The second you have class involved on any level, whether you just use 'with' on records in class method or you use with on class instances you are in trouble. It doesn't even have to be nested 'with'.
Why not mark only the "anonymous" (for lack of a better term) version as deprecated?
To be honest though I too don't see it as a necessary keyword any more. I understand back in the day it was useful for saving typing when accessing a lot of fields in a record. These days records can have methods - a better way of accessing their fields, I think :)
I wonder - why isn't "with namespace pollution" a compiler warning?
ReplyDeleteI had to change something in some old Borland Pascal program today and I had to restraint myself very forcefully not to start removing with statements. Otherwise I would still sit at work trying to figure out all the bugs that would have occurred afterwards. With statements are evil but nested multi-with statements in object oriented code are the devils own invention:
ReplyDeleteProcedure TSomeObject.doSomething;
Begin
With someProperty, someFieldOfThatProperty do begin
{ ... }
With someOtherProperty do begin
SomeField := someProperty.SomeField;
End;
End;
End;
Lars Fosdal Can you imagine if Embarcadero snuck in an "ambiguous reference" hint or warning that was generated whenever an identifier inside a with conflicts with an identically named identifier defined outside the with's scope.
ReplyDeleteIt wouldn't be very pascalish though. The same ambiguity exists at the unit, class and function level.
With a, b, c do is Pascal's answer to MI. And evil for the same reasons.
ReplyDeleteRemember: A Kitten dies each time you use WITH. Don't do it and save a precious life - and the sanity of the poor schmuck that has to maintain your code. :-)
ReplyDeleteBill Meyer MI?
ReplyDeleteKenneth Cochran Multiple Inheritance. Also plagued by name collision issues.
ReplyDeleteEvery time I do it, God saves a kitten.
ReplyDeleteBill Meyer Aah, I see. Every language needs an abuse prone feature and this was Pascal's contribution.
ReplyDeleteKenneth Cochran Well, that and FreeAndNil();
ReplyDeleteBill Meyer
ReplyDeleteActually interfaces are the answer to MI, and they do rather fine job for hat purpose :-). With serves only evil developers :-D
Jeroen Wiert Pluimers So many entries, just to say "Don't!" ;)
ReplyDeleteBill Meyer every time it is fun to see the reactions.
ReplyDeleteI did a write up about it years ago on my own blog comparing it with similar features in other languages.
ReplyDeletehttp://codeelegance.blogspot.com/2011/08/with-statement.html
Kenneth Cochran I had to check, but Wirth kept "with" in Modula 2 and Oberon. However in Oberon, it appears that the "guard" cannot be a list, so with a, b do is not supported.
ReplyDeleteMaybe they should introduce a closing "without" - that way nested withs maintain order.
ReplyDeleteIf it could not be nested, and did not accept a list, and was supported in the debugger, it would be less offensive. But that is a lot of ifs....
ReplyDeleteBill Meyer
ReplyDeleteIt is more than offensive. The danger is that it allows changes in unrelated code to cause sudden bugs in it. Offensive in this case is probably the understatement of the century :-D
Bill Meyer Only place where 'with' doesn't pose any real danger are standalone functions and procedures that operate on records.
ReplyDeleteThe second you have class involved on any level, whether you just use 'with' on records in class method or you use with on class instances you are in trouble. It doesn't even have to be nested 'with'.
What do you think of slightly changed syntax:
ReplyDeletewith a := Something do
a.Foo
?
I like that variation - it keeps the space-saving aspect but makes what it's operating on completely clear.
David Millington No. No. No. No. Noooooooo! That encourages people to use `with`. And it should be discouraged.
ReplyDeleteSee Hallvard's second link.
The only compiler changes for it should be to mark it deprecated for a few versions, than kill it.
Why not mark only the "anonymous" (for lack of a better term) version as deprecated?
ReplyDeleteTo be honest though I too don't see it as a necessary keyword any more. I understand back in the day it was useful for saving typing when accessing a lot of fields in a record. These days records can have methods - a better way of accessing their fields, I think :)
David Millington because everytime you would write such a with, you should have written a method that can be unit-tested.
ReplyDeleteMy coworker Martin Wienold always successfully slaps his own hand when he feels the temptation to use with ;)
ReplyDeleteStefan Glienke Yes, I do.
ReplyDelete