Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-08

'with' is evil, isn't it?

87 messages · 29 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Max Vlasov

Hi,

Personally I stopped using 'with' keyword long time ago, but there are code fragments from the past and today I fixed a little bug showing again that it's a evil. TCanvas in lazarus has width and height properties while in Delphi it hasn't (at least some time ago). So the code below leads to different results in lazarus and Delphi, at least for design-time drawing.

procedure TControlDescendant.Paint;
begin
  with Canvas do
  begin
      Rectangle(0, 0, Width, Height);
  edn;
end;

So not only the 'with' context can silently change while the project is evolving, it can also change while it's being ported...

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110802/f250e1c3/attachment.html>

Reply by email

silvioprog
to Rich Saunders

+1.

Silvio Cl?cio =============================================== Blog - <silvioprog.com.br> Twitter - <twitter.com/silvioprog> LazSolutions - <code.google.com/p/lazsolutions> LazWebSolutions - <code.google.com/p/lazwebsolutions> Lazarus-BR - <groups.google.com.br/group/lazarus-br?hl=pt-BR> =============================================== ? ?* Conhe?a nosso canal IRC sobre Lazarus: #lazarus-br * ===============================================

Reply by email

Marcos Douglas
to Max Vlasov: Personally I stopped using 'with' keyword long time ago, but there are code fragments…

2011/8/2 Max Vlasov :

Show quoted text 18 lines
Hi, Personally I stopped using 'with' keyword long time ago, but there are code fragments from the past and today I fixed a little bug showing again that it's a evil. TCanvas in lazarus has width and height properties while in Delphi it hasn't (at least some time ago). So the code below leads to different results in lazarus and Delphi, at least for design-time drawing. procedure TControlDescendant.Paint; begin ? with Canvas do ? begin ????? Rectangle(0, 0, Width, Height); ? edn; end; So not only the 'with' context can silently change while the project is evolving, it can also change while it's being ported...

IMHO, 'with' should have an implicit pointer like 'self' (could be 'this' or whatever).

Eg:

procedure TControlDescendant.Paint;
begin
  with Canvas do
  begin
      this.Rectangle(0, 0, this.Width, this.Height);
  edn;
end;

Marcos Douglas

Reply by email

ik
to Marcos Douglas
Marcos Douglas wrote 35 lines
2011/8/2 Max Vlasov : > Hi, > > Personally I stopped using 'with' keyword long time ago, but there are code > fragments from the past and today I fixed a little bug showing again that > it's a evil. TCanvas in lazarus has width and height properties while in > Delphi it hasn't (at least some time ago). So the code below leads to > different results in lazarus and Delphi, at least for design-time drawing. > > procedure TControlDescendant.Paint; > begin > with Canvas do > begin > Rectangle(0, 0, Width, Height); > edn; > end; > > So not only the 'with' context can silently change while the project is > evolving, it can also change while it's being ported... IMHO, 'with' should have an implicit pointer like 'self' (could be 'this' or whatever). Eg: procedure TControlDescendant.Paint; begin with Canvas do begin this.Rectangle(0, 0, this.Width, this.Height); edn; end;

That's also bad. Because I can use for example "with" the following way:

with area, canvas do
  begin
    Rectangle(0,0, with, height);
  end;

If you'll have "this" or "self" or $_ (in perl :)) it still contain the same problem. I prefer explicit code then implicit code. It's more readable and less error prone.

I think that "with" like "goto" need to be enabled by special parameter and not allowed by default.

Marcos Douglas

Ido

Show quoted text 7 lines
-- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110802/95f35289/attachment.html>

Reply by email

cobines
to Marcos Douglas: 2011/8/2 Max Vlasov : IMHO, 'with' should have an implicit pointer like 'self' (could be…

Yes, it is treacherous. I try not to use it. Maybe if it only allowed to refer to properties, functions of the "with" object, but it also allows outer scope and you never know how the classes will change in the future. Suddenly your code refers to entirely different data, because someone decided to add a property to the "with" object.

Does it have any performance advantage (in the generated code)?

cobines

Reply by email

Marcos Douglas
to ik: That's also bad. Because I can use for example "with" the following way: with area,…

2011/8/2 ik :

Show quoted text 13 lines
That's also bad. Because I can use for example "with" the following way: with area, canvas do ? begin ??? Rectangle(0,0, with, height); ? end; If you'll have "this" or "self" or $_ (in perl :)) it still contain the same problem. I prefer explicit code then implicit code. It's more readable and less error prone. I think that "with" like "goto" need to be enabled by special parameter and not allowed by default.

Yep... I forgot that sintaxe option because I never used. Forget what I said.

Marcos Douglas

Reply by email

Jürgen Hestermann
to Max Vlasov: Personally I stopped using 'with' keyword long time ago, but there are code fragments…
Personally I stopped using 'with' keyword long time ago, but there

are code fragments from the past and today I fixed a little bug showing again that it's a evil.

TCanvas in lazarus has width and height properties while in Delphi it

hasn't (at least some time ago). So the code below leads to different results in lazarus and Delphi, at least for design-time drawing.

Show quoted text 8 lines
procedure TControlDescendant.Paint; begin with Canvas do begin Rectangle(0, 0, Width, Height); edn; end; So not only the 'with' context can silently change while the project

is evolving, it can also change while it's being ported...

I don't know what "Width" and "Height" refer to in Delphi if Canvas has no such properties. In general I would expect to get an "unknown identifier" error message in this case. I think that the possibility of correct syntax (but different behaviour) is not very high. But of course, porting code is always an adventure.

In general I find the "with" statement very useful and have used and do use it a lot. Though it must be used in well defined short code blocks only. If you have very convoluted data structures with deeply nested arrays and records and pointers to them then it is a benefit not to be forced to write the same expression over and over again. And it also saves the program from calculating array indices and other references in these expressions multiple times so it speeds up the code too. I.e., if you have an expression like this:

----------------------------------------------------------------------- AusdehnungInMeter :=
(Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[length(Qarray[QuaderNr]^.Teilung[R].Einteilungen)+1] -

Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[1]) *

EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;
-----------------------------------------------------------------------

it is much easier to read (and calculate) in a with statement:

-----------------------------------------------------------------------
with Uebergabe^, Qarray[QuaderNr]^.Teilung[R] do
   AusdehnungInMeter := (Feldgrenzen[length(Einteilungen)+1] -
                                       Feldgrenzen[1]) *
EinheitAuswahl[Einheit.Koord[R]].Faktor;
-----------------------------------------------------------------------

It also saves you from typos within some of the expressions because you only have to type them once. Identifiers have to be unique to make it work but I never had a problem with a with statement so far.

Reply by email

Mark Morgan Lloyd
to Hans-Peter Diettrich: This<g> will fail with nested With's, or a With with multiple expressions. A nicer syntax…
Hans-Peter Diettrich wrote 19 lines
Marcos Douglas schrieb: > IMHO, 'with' should have an implicit pointer like 'self' (could be > 'this' or whatever). This<g> will fail with nested With's, or a With with multiple expressions. A nicer syntax would require only an "." for your "this.". > Eg: > > procedure TControlDescendant.Paint; > begin > with Canvas do > begin > this.Rectangle(0, 0, this.Width, this.Height); .Rectangle(0,0, .Width, .Height); > edn; > end;

One I've floated elsewhere is to allow with to define an alias with the same notation as a constant:

   with tsm= TSming(caller^) do begin
     while tsm.Count <= writePos do
       tsm.Append('');
Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Martin
to Jürgen Hestermann: are code fragments from the past and today I fixed a little bug showing again that it's a…
J?rgen Hestermann wrote 30 lines
In general I find the "with" statement very useful and have used and do use it a lot. Though it must be used in well defined short code blocks only. If you have very convoluted data structures with deeply nested arrays and records and pointers to them then it is a benefit not to be forced to write the same expression over and over again. And it also saves the program from calculating array indices and other references in these expressions multiple times so it speeds up the code too. I.e., if you have an expression like this: ----------------------------------------------------------------------- AusdehnungInMeter := (Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[length(Qarray[QuaderNr]^.Teilung[R].Einteilungen)+1] - Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[1]) * EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor; ----------------------------------------------------------------------- it is much easier to read (and calculate) in a with statement: ----------------------------------------------------------------------- with Uebergabe^, Qarray[QuaderNr]^.Teilung[R] do AusdehnungInMeter := (Feldgrenzen[length(Einteilungen)+1] - Feldgrenzen[1]) * EinheitAuswahl[Einheit.Koord[R]].Faktor; -----------------------------------------------------------------------

Why put Uebergabe^ in the with? It appears only once?

Assuming objects, better add helper methods

function TFooTeilung.GetLastFirstDiff;
begin
   Result := Feldgrenzen[ length(Einteilungen)+1 ] - Feldgrenzen[1];
end
AusdehnungInMeter :=
    Qarray[QuaderNr]^.Teilung[R].  GetLastFirstDiff
    *  EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;

You can also introduce
FeldgrenzenBackwards[x]
where 0 returns the last, 1 the one before last ....

If it may be other than last and first, give 2 params to GetLastFirstDiff( ElemFromEndIdx, ElemFromStartIdx ) eg GetLastFirstDiff(0,0) for Last-First

Would further shorten this (assuming that Einteilungen and Feldgrenzen are of the same length ?)

IMHO, that makes it much more readable.

you can even add an appropriately named method to the object returned by "Qarray[QuaderNr]^" , if it is an object (or record with method)

AusdehnungInMeter :=
    Qarray[QuaderNr]^.  GetLastFirstDiffForTeilung(R)
    *  EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;

OR
AusdehnungInMeter :=
Qarray[QuaderNr]^. GetLastFirstDiffForTeilungFooBar(R, Uebergabe)

and do the multiplikation inside that (you got Uebergabe and R

Martin

Reply by email

Jürgen Hestermann
to Martin
Show quoted text 5 lines
> ----------------------------------------------------------------------- > with Uebergabe^, Qarray[QuaderNr]^.Teilung[R] do > AusdehnungInMeter := (Feldgrenzen[length(Einteilungen)+1] - > Feldgrenzen[1]) * >
EinheitAuswahl[Einheit.Koord[R]].Faktor;
> ----------------------------------------------------------------------- > Why put Uebergabe^ in the with? It appears only once?

Yes, that's true. I just picked an arbitrary example from my code to get the idea. I have lots of with statements with similar "with-variables". Sometimes they are used only once and in other cases they are used more often.

Show quoted text 5 lines
Assuming objects, better add helper methods function TFooTeilung.GetLastFirstDiff; begin Result := Feldgrenzen[ length(Einteilungen)+1 ] - Feldgrenzen[1]; end

I don't want to add runtime penalties by calling functions (with stack handling overhead).

Show quoted text 6 lines
AusdehnungInMeter := Qarray[QuaderNr]^.Teilung[R]. GetLastFirstDiff * EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor; You can also introduce FeldgrenzenBackwards[x] where 0 returns the last, 1 the one before last ....

Same reason: It's slower and does not add any benefit.

Of course, there is an inifite way of coding things and the with statement is one of them.

Reply by email

Hans-Peter Diettrich
to Marcos Douglas: 2011/8/2 Max Vlasov : IMHO, 'with' should have an implicit pointer like 'self' (could be…
IMHO, 'with' should have an implicit pointer like 'self' (could be 'this' or whatever).

This<g> will fail with nested With's, or a With with multiple expressions.

A nicer syntax would require only an "." for your "this.".

Show quoted text 7 lines
Eg: procedure TControlDescendant.Paint; begin with Canvas do begin this.Rectangle(0, 0, this.Width, this.Height);
         .Rectangle(0,0, .Width, .Height);
edn; end;

DoDi

Reply by email

Marcos Douglas
to Mark Morgan Lloyd: One I've floated elsewhere is to allow with to define an alias with the same notation…
Hans-Peter Diettrich wrote 20 lines
Marcos Douglas schrieb: > IMHO, 'with' should have an implicit pointer like 'self' (could be > 'this' or whatever). This<g> will fail with nested With's, or a With with multiple expressions. A nicer syntax would require only an "." for your "this.". > Eg: > > procedure TControlDescendant.Paint; > begin > with Canvas do > begin > this.Rectangle(0, 0, this.Width, this.Height); .Rectangle(0,0, .Width, .Height); > > end;
     end;

OK, could be... but not prevents confusion of properties.

Mark Morgan Lloyd wrote 6 lines
One I've floated elsewhere is to allow ?with ?to define an alias with the same notation as a constant: ?with tsm= TSming(caller^) do begin ? ?while tsm.Count <= writePos do ? ? ?tsm.Append('');

I like it, but FPC's team doesn't will, I think... Alias already was proposed even to Units but did not approved.

Marcos Douglas

Reply by email

cobines
to Jürgen Hestermann: are code fragments from the past and today I fixed a little bug showing again that it's a…

2011/8/2 J?rgen Hestermann :

And it also saves the program from calculating array indices and other references in these expressions multiple times so it speeds up the code too.

I didn't know that, but indeed it does.

Show quoted text 23 lines
I.e., if you have an expression like this: ----------------------------------------------------------------------- AusdehnungInMeter := (Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[length(Qarray[QuaderNr]^.Teilung[R].Einteilungen)+1] - ?Qarray[QuaderNr]^.Teilung[R].Feldgrenzen[1]) * ?EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor; ----------------------------------------------------------------------- it is much easier to read (and calculate) in a with statement: ----------------------------------------------------------------------- with Uebergabe^, Qarray[QuaderNr]^.Teilung[R] do ?AusdehnungInMeter := (Feldgrenzen[length(Einteilungen)+1] - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Feldgrenzen[1]) * ?EinheitAuswahl[Einheit.Koord[R]].Faktor; -----------------------------------------------------------------------

In case Qarray[QuaderNr]^.Teilung[R] is an object I usually do:

tmp := Qarray[QuaderNr]^.Teilung[R];
AusdehnungInMeter :=  (tmp.Feldgrenzen[length(tmp.Einteilungen)+1] -
tmp.Feldgrenzen[1]) *
EinheitAuswahl[Uebergabe^.Einheit.Koord[R]].Faktor;

It results in a similar code than using "with", because from what I see "with" creates an implicit local var or uses a register to store the address.

For records one could use tmp as a pointer to the record, and then refer to tmp^.

cobines

Reply by email

Hans-Peter Diettrich
to Marcos Douglas: On Tue, Aug 2, 2011 at 2:21 PM, Hans-Peter Diettrich end; OK, could be... but not…
Show quoted text 22 lines
On Tue, Aug 2, 2011 at 2:21 PM, Hans-Peter Diettrich wrote: > Marcos Douglas schrieb: > >> IMHO, 'with' should have an implicit pointer like 'self' (could be >> 'this' or whatever). > This<g> will fail with nested With's, or a With with multiple expressions. > > A nicer syntax would require only an "." for your "this.". > >> Eg: >> >> procedure TControlDescendant.Paint; >> begin >> with Canvas do >> begin >> this.Rectangle(0, 0, this.Width, this.Height); > .Rectangle(0,0, .Width, .Height); >> end; end; OK, could be... but not prevents confusion of properties.

No chance. The syntax doesn't allow for
<identifier> <identifier> "." ...

DoDi

Reply by email

Hans-Peter Diettrich
to Jürgen Hestermann: are code fragments from the past and today I fixed a little bug showing again that it's a…
Show quoted text 5 lines
with Uebergabe^, Qarray[QuaderNr]^.Teilung[R] do AusdehnungInMeter := (Feldgrenzen[length(Einteilungen)+1] - Feldgrenzen[1]) * EinheitAuswahl[Einheit.Koord[R]].Faktor;

This is very close to the explicit pointer version:

   U := Uebergabe;
   Q := Qarray[QuaderNr]^.Teilung[R];
   AusdehnungInMeter := (Q.Feldgrenzen[length(Einteilungen)+1] -
                         Q.Feldgrenzen[1]) *
EinheitAuswahl[U^.Einheit.Koord[R]].Faktor;

Only the declarations for U and Q have to be added, and the debugger will have no problem with guessing the correct prefix.

DoDi

Reply by email

Luiz Americo Pereira Camara
to Max Vlasov: Personally I stopped using 'with' keyword long time ago, but there are code fragments…
Max Vlasov wrote 19 lines
Hi, Personally I stopped using 'with' keyword long time ago, but there are code fragments from the past and today I fixed a little bug showing again that it's a evil. TCanvas in lazarus has width and height properties while in Delphi it hasn't (at least some time ago). So the code below leads to different results in lazarus and Delphi, at least for design-time drawing. procedure TControlDescendant.Paint; begin with Canvas do begin Rectangle(0, 0, Width, Height); edn; end; So not only the 'with' context can silently change while the project is evolving, it can also change while it's being ported...

I also ran into this problem while porting Delphi code

http://lazarusroad.blogspot.com/2007/02/traps-of-delphi-to-lazarus-conversion.html

Luiz

Reply by email

Max Vlasov
to Marcos Douglas: 2011/8/2 Max Vlasov : IMHO, 'with' should have an implicit pointer like 'self' (could be…
Marcos Douglas wrote 28 lines
2011/8/2 Max Vlasov : > Hi, > > Personally I stopped using 'with' keyword long time ago, but there are code > fragments from the past and today I fixed a little bug showing again that > it's a evil. > ..... > > So not only the 'with' context can silently change while the project is > evolving, it can also change while it's being ported... IMHO, 'with' should have an implicit pointer like 'self' (could be 'this' or whatever). Eg: procedure TControlDescendant.Paint; begin with Canvas do begin this.Rectangle(0, 0, this.Width, this.Height); edn; end;

Reading all the discussion and suggestions, some thoughts came
1. Introducing a check in the compiler setting (or a conditional define) that could force the developer to use self inside 'with' constructions. So with this setting on, any access to fields, properties or methods will require explicit self or 'identifier not found' will be fired. This solution still won't save from many problem situation (including the one I gave an example), but at least it is compatible with existing Delphi syntax and make some constructions more readable

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). The developer in this case has at least options to rename local variables, include self for fields to resolve the problem or not using with if there are no other options.
In contrary to 1. this would solve the example I gave since there are two widths and heights in the context of 'with' construction.

What do you think?

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110803/7fb253a6/attachment-0001.html>

Reply by email

Michael Schnell
to Max Vlasov: Reading all the discussion and suggestions, some thoughts came 1. Introducing a check in…
Max Vlasov wrote
Reading all the discussion and suggestions, some thoughts came

I never tried "with" with Lazarus, but with Delphi (I never tried the newest versions) it was not possible to view the value of a "with"-handled variable by pointing the mouse on it.

The current and any improved behavior of the compiler should allow for decent debugging right away.

-Michael

Reply by email

Michael Schnell
to Jürgen Hestermann: are code fragments from the past and today I fixed a little bug showing again that it's a…
J?rgen Hestermann wrote
In general I find the "with" statement very useful and have used and do use it a lot.

If you are clever enough to avoid confusion ;) . (Such as a nested with that defines the same identifier for both "with"ed record and maybe same is also defined as the "implicitly with"ed "self" (instance record).

And it also saves the program from calculating array indices and other references in these expressions multiple times so it speeds up the code too.

A decent compiler should be able to perform this optimization on it's own account.

-Michael

Reply by email

Alexander Klenin
to Max Vlasov: Reading all the discussion and suggestions, some thoughts came 1. Introducing a check in…

I also use 'with' extensively, despite the risks,
since with the right usage the readablity gains are considerable.

2011/8/3 Max Vlasov :

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 :(

Alexander S. Klenin

Reply by email

Michael Van Canneyt
to Alexander Klenin
Alexander Klenin wrote 17 lines
I also use 'with' extensively, despite the risks, since with the right usage the readablity gains are considerable. 2011/8/3 Max Vlasov : > 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.

And resolving one perceived problem (with) by forcing people to use 'self'
- which is reserved for the current instance of a class or object - means introducing a new ambiguity, which has *exactly* the same problem as the original when used inside classes. (not to mention that there would then be no way to access the class instance 'self' inside a 'with')

Again not very consequent.

Michael.

Reply by email

Michael Schnell
to Max Vlasov: Reading all the discussion and suggestions, some thoughts came 1. Introducing a check in…
Max Vlasov wrote
1. Introducing a check in the compiler setting (or a conditional define) that could force the developer to use self inside 'with' constructions

As you can consider any class functions code to be implicitly included in a "with self" clause this could be done more generally: using an "naked" identifier that is specified by multiple (nested) "with"s.

-Michael

Reply by email

Alexander Klenin
to Michael Van Canneyt: Frankly, I don't understand the discussion. I use 'with' all the time because it…
Michael Van Canneyt wrote 7 lines
> 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.

Agreed.

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.

This is why I suggested to restrict warnings only to a cases where actual ambiguity exists, which is actually quite rare. Maybe even warning is too much, and it should be a hint.

Anyway, my preferred solution would be to allow aliases in 'with' statement, which would improve readability even further while sacrificing only a few characters:

with a := MyCompomentList[0] do begin
  Rectangle(0, 0, a.Width, a.Height);
end;

No chance of
Alexander S. Klenin

Reply by email

Lukasz Sokol
to Alexander Klenin
Alexander Klenin wrote 29 lines
On Wed, Aug 3, 2011 at 22:34, Michael Van Canneyt wrote: > >> 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. Agreed. > 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. This is why I suggested to restrict warnings only to a cases where actual ambiguity exists, which is actually quite rare. Maybe even warning is too much, and it should be a hint. Anyway, my preferred solution would be to allow aliases in 'with' statement, which would improve readability even further while sacrificing only a few characters: with a := MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height); end; No chance of ambiguity at all.

IM(H)O,

with a:TMyType := MyComponentList[0] do
begin // 'a' only valid from here, spew an error if 'a' is declared, even if different type
end;  // 'a' only valid until here

-> based on: look at what E:Exception in try..except..end; does ->

My 2gr.

Lukasz

Reply by email

Graeme Geldenhuys
to Alexander Klenin: On Wed, Aug 3, 2011 at 22:34, Michael Van Canneyt Agreed. This is why I suggested to…
Alexander Klenin wrote 7 lines
Anyway, my preferred solution would be to allow aliases in 'with' statement, which would improve readability even further while sacrificing only a few characters: with a := MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height); end;

A simple solution to something which I don't think is a problem either. [I fully agree with Michael van Canneyt here]

Simply use a better IDE that can do code completion, identifier completion or code prediction. If your IDE of choice doesn't cater for this, speak to those developers or start submitting patches.

If every compiler must start adding hints, warnings or extra parameters or languages features just because your can't type fast enough.... well, than is your problem. Learn to type faster, or use a better IDE.

Object Pascal is quite clear on defining scope. So I really don't see an issue with you don't like it, don't use it.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 12 lines
On 08/03/2011 02:00 PM, Alexander Klenin wrote: > Anyway, my preferred solution would be to allow aliases in 'with' statement, > which would improve readability even further while sacrificing only a > few characters: > > with a := MyCompomentList[0] do begin > Rectangle(0, 0, a.Width, a.Height); > end; A simple solution to something which I don't think is a problem either. [I fully agree with Michael van Canneyt here]

I agree the above is indeed an acceptable solution.

But I do think it is a corner case, because it goes against pascal philosophy which says that all identifiers must be declared prior to being used.

The
On E : Exception do
is a Borland hack, which I'm not entirely happy with either. They should have forced people to declare the E in the function variable block. But since we already have this one, I could live with the above. (albeit grudgingly - it puts the door open for many other more ugly things).

Michael.

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt
Michael Van Canneyt wrote 7 lines
> A simple solution to something which I don't think is a problem either. > [I fully agree with Michael van Canneyt here] I agree the above is indeed an acceptable solution. But I do think it is a corner case, because it goes against pascal philosophy which says that all identifiers must be declared prior to being used.

OK, I see how my message could have been misleading. :)

I meant I agreed with your statement that 'with' is not really a problem, so why look for a solution. If you don't feel comfortable with it, don't use it.

I do NOT agree that we should introduce the alias variable as Alexander suggested. As you mentioned, it is done in 'on E: Exception do', but it does indeed go against the normal language rules of Object Pascal. We should not promote more Borland "hacks" like that.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Mark Morgan Lloyd
to Michael Van Canneyt: I agree the above is indeed an acceptable solution. But I do think it is a corner case,…
Michael Van Canneyt wrote 21 lines
On Wed, 3 Aug 2011, Graeme Geldenhuys wrote: > On 08/03/2011 02:00 PM, Alexander Klenin wrote: >> Anyway, my preferred solution would be to allow aliases in 'with' >> statement, >> which would improve readability even further while sacrificing only a >> few characters: >> >> with a := MyCompomentList[0] do begin >> Rectangle(0, 0, a.Width, a.Height); >> end; > > > A simple solution to something which I don't think is a problem either. > [I fully agree with Michael van Canneyt here] I agree the above is indeed an acceptable solution. But I do think it is a corner case, because it goes against pascal philosophy which says that all identifiers must be declared prior to being used.

How about

with const a = MyCompomentList[0] do begin
   Rectangle(0, 0, a.Width, a.Height);
end;

a is, after all, a constant: it can't be changed and doesn't occupy any storage.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Hans-Peter Diettrich
to Jürgen Hestermann: Yes, of course. But it's just so much easier to use "with" which does the same in the…
Show quoted text 7 lines
cobines schrieb: > In case Qarray[QuaderNr]^.Teilung[R] is an object I usually do: > tmp := Qarray[QuaderNr]^.Teilung[R]; > Yes, of course. But it's just so much easier to use "with" which does the same in the background and save you from adding local variables yourself.

With is only "easier" to use from the writers viewpoint. For an reader it's much harder to figure out what's going on, and code is more often read than written.

When something has to be changed later, it's often recommended to remove the With first, before trying to change anything else.

When something changed in the related data types, then it's not clear why the code fails now, because it's impossible to reconstruct the *previous* meaning (without reverting everything to an earlier state).

IMO there exist only very few situations, where With is both safe to use and easy to read.

DoDi

Reply by email

Michael Fuchs
to Mark Morgan Lloyd: How about with const a = MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height);…
Mark Morgan Lloyd wrote
with const a = MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height); end;

What is wrong with the existing solution, declaring a variable a and use it?

var
   a: TComponent;
  ...
a := MyCompomentList[0];
Rectangle(0, 0, a.Width, a.Height);

And I agree: switching the with off in compiler settings would a nice feature.

Michael

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt: Frankly, I don't understand the discussion. I use 'with' all the time because it…
Show quoted text 7 lines
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.

Everybody can do whatever he likes, in his own code, that never is used or read by other people. I.e. your last statement should read:

If you want your code be used, read and understood by other people, then
don't use With.

DoDi

Reply by email

Michael Schnell
to Alexander Klenin: On Wed, Aug 3, 2011 at 22:34, Michael Van Canneyt Agreed. This is why I suggested to…
Alexander Klenin wrote
with a := MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height); end;

Here defining a as a pointer would do away with the with and the begin .. end.

By allowing for C-like defining of cariables we could write something like

   var a TMyPointer := MyCompomentList[0];
  Rectangle(0, 0, a.Width, a.Height);

(this might or might not be a good idea)
- Michael

Reply by email

Michael Van Canneyt
to Mark Morgan Lloyd: How about with const a = MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height);…
Mark Morgan Lloyd wrote 31 lines
Michael Van Canneyt wrote: > On Wed, 3 Aug 2011, Graeme Geldenhuys wrote: > >> On 08/03/2011 02:00 PM, Alexander Klenin wrote: >>> Anyway, my preferred solution would be to allow aliases in 'with' >>> statement, >>> which would improve readability even further while sacrificing only a >>> few characters: >>> >>> with a := MyCompomentList[0] do begin >>> Rectangle(0, 0, a.Width, a.Height); >>> end; >> >> >> A simple solution to something which I don't think is a problem either. >> [I fully agree with Michael van Canneyt here] > > I agree the above is indeed an acceptable solution. > > But I do think it is a corner case, because it goes against pascal > philosophy which says that all identifiers must be declared prior to being > used. How about with const a = MyCompomentList[0] do begin Rectangle(0, 0, a.Width, a.Height); end; a is, after all, a constant: it can't be changed and doesn't occupy any storage.

Sorry, but that's even more ugly.

My point was that in pascal, you explicitly separate declaration blocks from code blocks. The above construct does away with that by putting the 'declaration' in the code itself. Personally, I do not welcome such a change. There is a reason for this separation.

Due to circumstances, I program a lot of Javascript these days. It's totally unreadable because it is littered with such 'easy-going' constructs. You can do some nice tricks with it, but at the same time, it's much more error prone than Pascal.

So, any attempt to introduce such 'features' will never be met with applause from me. (and that's putting it mildly ;))

I often wonder why people keep asking for such things in Pascal.

To me, introduction of features found in other languages make it less Object Pascal, when bringing in fact very little gain. I've seen many 'features' added, I even use them. But none of them have made me more productive or made it easier to debug my code.

I like to compare it with the game of chess:
It's not like the chess community introduces new moves every year to make it interesting or cool.

If you don't like the strict rules of chess, go play something else. For example, "Magic: the gathering". They introduce new cards all the time: have fun, knock yourself out ! (I don't know if it still exists, at that)

Michael.

Reply by email

Fr0sT

I personally use "with" widely and never experienced any troubles with it but I know that many people just hate this statement (see discussion on Emb-ro forums and one of the most popular requests on Emb-ro quality central).
I guess problem could be solved by modifying statement like this:

  with some.very.very.long.name as foo, some.other.giant.object.name as bar do
    foo.Field := bar.Field

but it IMHO violates Pascal syntax philosophy.

Reply by email

Max Vlasov
to Michael Van Canneyt: Frankly, I don't understand the discussion. I use 'with' all the time because it…
Michael Van Canneyt wrote 41 lines
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 : > >> 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,
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?

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110803/d95ede42/attachment.html>

Reply by email

Lukasz Sokol
to Michael Schnell: Here defining a as a pointer would do away with the with and the begin .. end. By…
Michael Schnell wrote 13 lines
On 08/03/2011 02:00 PM, Alexander Klenin wrote: > with a := MyCompomentList[0] do begin > Rectangle(0, 0, a.Width, a.Height); > end; Here defining a as a pointer would do away with the with and the begin .. end. By allowing for C-like defining of cariables we could write something like var a TMyPointer := MyCompomentList[0]; Rectangle(0, 0, a.Width, a.Height);

Except that a here is _not_really_ _any_ variable... and neither it should be.

I think the idea [sh|w]ould be that

s/[identifier a]/MyComponentList[0] (plaintext substitution of 'a' with MyComponentList[0]) on the text block from begin to end should be transparent, (after the compiler checks the 'a' is correctly typed, hence my idea of telling it _which_ type you're using of 'a' so it doesn't 'guess', but _check_ instead) and THEN optimizations applied by compiler...

or ! if we want to be Pascal Explicit :

with MyComponentList[0] as a:TMyType do
begin
end;

(I guess somebody had this idea earlier but I suddenly like it for it's straightforward)

(this might or might not be a good idea) - Michael

L.

Reply by email

Lukasz Sokol
to Michael Van Canneyt: I agree the above is indeed an acceptable solution. But I do think it is a corner case,…
Michael Van Canneyt wrote 10 lines
The On E : Exception do is a Borland hack, which I'm not entirely happy with either. They should have forced people to declare the E in the function variable block. But since we already have this one, I could live with the above. (albeit grudgingly - it puts the door open for many other more ugly things). Michael.

Except that in the with construct the named alias will not be an instance of variable, but rather a way of _naming_ it shorter, an _alias_; I agree that making it a variable will create all sorts of problems regarding memory management, lifetime management and so on; but the named alias would only live in the block following the with, and could be forced to be strong-typed too. Think plaintext substitution before compilation...
(and yes if some code tools (not CodeTools ;) or ide's have a problem with the 'with' as it is now, THEY should be fixed).

L.

Reply by email

Michael Van Canneyt
to Max Vlasov: On Wed, Aug 3, 2011 at 3:34 PM, Michael Van Canneyt Michael, one example from Sql if you…
Max Vlasov wrote 43 lines
On Wed, Aug 3, 2011 at 3:34 PM, Michael Van Canneyt 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 : 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.

Show quoted text 8 lines
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.

Reply by email

Michael Schnell
to Lukasz Sokol: Except that a here is _not_really_ _any_ variable... and neither it should be. I think…
Lukasz Sokol wrote
Except that a here is _not_really_ _any_ variable... and neither it should be.

As already said the compiler optimization should be able to do away with unnecessary variable (or introduce hidden variables if necessary).

But OTOH I am not convinced that allowing for C-like defining of variables anywhere in the code is really a good idea.

-Michael

Reply by email

Max Vlasov
to Michael Van Canneyt: Huh ? Firebird does not, and they should not. It's clear from the statement that id is…
Michael Van Canneyt wrote 17 lines
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'.

Let's forget about the suggestion with mandatory self, it wasn't a good for plenty of reasons :). I'd left with the one that shows error when 'with' brings unambiguousness. I think there's no big problem with unique names like myspecialproperty or something like this, but there are also:

count, length, items, width, height

used many times in lcl and elsewhere (btw, it's interesting to know the name of yours in your example). Introducing the switch and enabling it now and forever will be like an investment to the future, you won't notice the difference right now, but it will make you safer later if some of the object used in 'with' statement introduce a property with one of those frequently used names and this could instantly change the context of some lines.

Anyway, it's not a big deal to encourage the developers who has many more important things to do, maybe a reason to look into the internals of freepascal myself and find out more :)

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110803/cc59c71e/attachment-0001.html>

Reply by email

David M. Lawrence
to Hans-Peter Diettrich: With is only "easier" to use from the writers viewpoint. For an reader it's much harder…

I would suggest for you who do not like "with" is to figure out ways to avoid using it yourselves, but leave it alone for those of us who find it useful.

Dave

Hans-Peter Diettrich wrote 30 lines
J?rgen Hestermann schrieb: > cobines schrieb: >> In case Qarray[QuaderNr]^.Teilung[R] is an object I usually do: >> tmp := Qarray[QuaderNr]^.Teilung[R]; > Yes, of course. But it's just so much easier to use "with" which does > the same in the background and save you from adding local variables > yourself. With is only "easier" to use from the writers viewpoint. For an reader it's much harder to figure out what's going on, and code is more often read than written. When something has to be changed later, it's often recommended to remove the With first, before trying to change anything else. When something changed in the related data types, then it's not clear why the code fails now, because it's impossible to reconstruct the *previous* meaning (without reverting everything to an earlier state). IMO there exist only very few situations, where With is both safe to use and easy to read. DoDi -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
------------------------------------------------------ David M. Lawrence | Home: (804) 559-9786 7471 Brook Way Court | Fax: (804) 559-9787 Mechanicsville, VA 23111 | Email: USA | http: http://fuzzo.com ------------------------------------------------------ "All drains lead to the ocean." -- Gill, Finding Nemo "We have met the enemy and he is us." -- Pogo "No trespassing 4/17 of a haiku" -- Richard Brautigan

Reply by email

Mark Morgan Lloyd
to Michael Van Canneyt: Sorry, but that's even more ugly. My point was that in pascal, you explicitly separate…
Michael Van Canneyt wrote 68 lines
On Wed, 3 Aug 2011, Mark Morgan Lloyd wrote: > Michael Van Canneyt wrote: >> On Wed, 3 Aug 2011, Graeme Geldenhuys wrote: >> >>> On 08/03/2011 02:00 PM, Alexander Klenin wrote: >>>> Anyway, my preferred solution would be to allow aliases in 'with' >>>> statement, >>>> which would improve readability even further while sacrificing only a >>>> few characters: >>>> >>>> with a := MyCompomentList[0] do begin >>>> Rectangle(0, 0, a.Width, a.Height); >>>> end; >>> >>> >>> A simple solution to something which I don't think is a problem either. >>> [I fully agree with Michael van Canneyt here] >> >> I agree the above is indeed an acceptable solution. >> >> But I do think it is a corner case, because it goes against pascal >> philosophy which says that all identifiers must be declared prior to >> being used. > > How about > > with const a = MyCompomentList[0] do begin > Rectangle(0, 0, a.Width, a.Height); > end; > > a is, after all, a constant: it can't be changed and doesn't occupy > any storage. Sorry, but that's even more ugly. My point was that in pascal, you explicitly separate declaration blocks from code blocks. The above construct does away with that by putting the 'declaration' in the code itself. Personally, I do not welcome such a change. There is a reason for this separation. Due to circumstances, I program a lot of Javascript these days. It's totally unreadable because it is littered with such 'easy-going' constructs. You can do some nice tricks with it, but at the same time, it's much more error prone than Pascal. So, any attempt to introduce such 'features' will never be met with applause from me. (and that's putting it mildly ;)) I often wonder why people keep asking for such things in Pascal. To me, introduction of features found in other languages make it less Object Pascal, when bringing in fact very little gain. I've seen many 'features' added, I even use them. But none of them have made me more productive or made it easier to debug my code. I like to compare it with the game of chess: It's not like the chess community introduces new moves every year to make it interesting or cool. If you don't like the strict rules of chess, go play something else. For example, "Magic: the gathering". They introduce new cards all the time: have fun, knock yourself out ! (I don't know if it still exists, at that)

Sure it's ugly. But with does have its uses, and anything which can be done to limit the scope for abuse has to be a Good Thing.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Alexsander Rosa
to Fr0sT: I personally use "with" widely and never experienced any troubles with it but I know that…

We use "with" to populate or display properties of objects from our in-house OPF. However we have some ground rules: most properties are mapped from tables (DAO pattern) and their names are in portuguese and with an underscore, like "valor_total".

A common code looks like this:
*with mCliente do begin
  edtNomeRazao.Text := Nome_Razao;
  edtDataNasc.Text := DateToStr(Data_Nascimento);
  edtLimiteCredito.Text := Format('.2n',[Limite_Credito]);
  ...
  end;
*
This works fine.

2011/8/3 Fr0sT

Show quoted text 16 lines
I personally use "with" widely and never experienced any troubles with it but I know that many people just hate this statement (see discussion on Emb-ro forums and one of the most popular requests on Emb-ro quality central). I guess problem could be solved by modifying statement like this: with some.very.very.long.name as foo, some.other.giant.object.name as bar do foo.Field := bar.Field but it IMHO violates Pascal syntax philosophy. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Atenciosamente, Alexsander da Rosa http://rednaxel.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110803/b9b840d5/attachment.html>

Reply by email

leledumbo
to Alexander Klenin: I also use 'with' extensively, despite the risks, since with the right usage the…
I think a warning if the name inside of 'with' overrides a name from outer

scope would be an acceptable compromise.

I agree with this solution, it doesn't change the syntax, yet it gives better chance to spot wrong scope of identifier which could happen during porting or upgrade.

View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-with-is-evil-isn-t-it-tp3219144p3223700.html Sent from the Free Pascal - Lazarus mailing list .

Reply by email

Jürgen Hestermann
to leledumbo
Show quoted text 8 lines
> I think a warning if the name inside of 'with' overrides a name from outer > scope would be an acceptable compromise. I agree with this solution, it doesn't change the syntax, yet it gives better chance to spot wrong scope of identifier which could happen during porting or upgrade.

We have the same issue here as it exists for for-variables: If you forgot to declare your local for-variable it helps to get warned if the variable name exists as a global or parent function variable too. So a warning that a reference within a with statement resolves to a variable outside the with statement would help finding bugs.

Reply by email

Sven Barth
to Michael Schnell: If you are clever enough to avoid confusion ;) . (Such as a nested with that defines the…
Michael Schnell wrote 13 lines
On 08/02/2011 06:39 PM, J?rgen Hestermann wrote: > > > In general I find the "with" statement very useful and have used and > do use it a lot. If you are clever enough to avoid confusion ;) . (Such as a nested with that defines the same identifier for both "with"ed record and maybe same is also defined as the "implicitly with"ed "self" (instance record). > And it also saves the program from calculating array indices and other > references in these expressions multiple times so it speeds up the > code too. A decent compiler should be able to perform this optimization on it's own account.

The code that calculates the indices and handles other references could have side effects, so the compiler would not be able to optimize them. If you use this code once inside the "with"-clause you tell the compiler to do that calculation only once and that you are aware of possible side effects (or thus not occuring side effects).

Regards,
Sven

Reply by email

Sven Barth
to Max Vlasov: Personally I stopped using 'with' keyword long time ago, but there are code fragments…
Max Vlasov wrote 19 lines
Hi, Personally I stopped using 'with' keyword long time ago, but there are code fragments from the past and today I fixed a little bug showing again that it's a evil. TCanvas in lazarus has width and height properties while in Delphi it hasn't (at least some time ago). So the code below leads to different results in lazarus and Delphi, at least for design-time drawing. procedure TControlDescendant.Paint; begin with Canvas do begin Rectangle(0, 0, Width, Height); edn; end; So not only the 'with' context can silently change while the project is evolving, it can also change while it's being ported...

I personally consider "with" as a statement of the category "from great power comes great responsibility" and thus "handle with care". "absolute" is another example of such a construct (and I like to use it in event handlers that have "TObject" as sender ^^).

Regards,
Sven

Reply by email

Michael Schnell
to Sven Barth: The code that calculates the indices and handles other references could have side…
Sven Barth wrote 7 lines
The code that calculates the indices and handles other references could have side effects, so the compiler would not be able to optimize them. If you use this code once inside the "with"-clause you tell the compiler to do that calculation only once and that you are aware of possible side effects (or thus not occuring side effects).

OK, with C a possible compiler-generated the hidden pointer variable is as "non-volatile" as an explicit variable without a "volatile" spec would be, while in Pascal virtually everything is considered volatile. this in fact might ask for side-effects.

-Michael

Reply by email

Max Vlasov
to Michael Schnell: +1 -Michael
Michael Schnell wrote 9 lines
On 08/03/2011 10:17 PM, Reimar Grabowski wrote: > I don't really get why this question is posted here and not on the fpc > list. > +1 -Michael

Actually, this particular case was also lcl-related. Anyone who written something in Delphi control-related with a construction

with Canvas do .... Width Height ...

(meaning the bounds of the control)
will be affected while porting something to Lazarus , because lcl Canvas has width and height while Delphi Canvas not. Luiz also mentioned a problem related to Canvas in his blog post.

I just thought about the phrase Sven mentioned ("handle with care") and tried to imagine myself many years ago applying this rule. The only general rule I think of could be "never use the properties of the object you writing method of in the 'with' construction, because it can appear in the mentioned object anytime soon". I doubt anyone can really follow such rule :)

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110804/21fef745/attachment-0001.html>

Reply by email

Alexander Klenin
to Max Vlasov

2011/8/4 Max Vlasov :

Show quoted text 15 lines
Anyone who written something in Delphi control-related with a construction with Canvas do .... Width Height ... (meaning the bounds of the control) will be affected while porting something to Lazarus , because lcl Canvas has width and height while Delphi Canvas not. Luiz also mentioned a problem related to Canvas in his blog post. I just thought about the phrase Sven mentioned ("handle with care") and tried to imagine myself many years ago applying this rule. The only general rule I think of could be "never use the properties of the object you writing method of in the 'with' construction, because it can appear in the mentioned object anytime soon". I doubt anyone can really follow such rule :)

Note that my proposal of using aliases would prevent this problem.

Alexander S. Klenin

Reply by email

Martin
to Alexander Klenin
Alexander Klenin wrote 9 lines
2011/8/4 Max Vlasov: > Anyone who written something in Delphi control-related with a construction > > with Canvas do .... Width Height ... > > (meaning the bounds of the control) > will be affected while porting something to Lazarus , because lcl Canvas has > width and height while Delphi Canvas not. Note that my proposal of using aliases would prevent this problem.

IF something like alias were to be introduced (and I am *not* for this), then pascal style, with a declaration above the code. It could then be used in a "with" statement, or anywhere else.

procedure foo;
var
   c: TObject; alias;
begin
OR
procedure foo;
alias
   c: TObject;
begin

and then
with c = SomeFoo do c.DoBar

OR
   c = SomeFoo; // "=" not ":=" it's an alias, it isn't an assignment
   c.DoBar;

Of course, the question is why? IT had to be defined where the difference to a normal variable is?
- Maybe refcounting? in "with" context, thatapplies for interfaces, since you can not do "with stringtype do"

Some people seemed to have argued "it saves a variable" => but whta does that save? a few bytes on the stack or a register? that isn't even guaranteed.
AFAIK, in current "with" the compiler allocates room for a temp variable => afaik it may even increase ref count of an interface? (But it does not gurantee this ref-count to be decreased at the end of the with block, afaik it does at the end of procedure (but that is just current implementation, and can't be relied on. Some people will remember, there was a discussion, using ref-counted interfaces in "with", for exactly the purpose of having them auto-freed at the end of the with block (so do format the output of a log) => and it does not work that way)

So currently "With" does NOT save a variable (it only saves the reader from spotting the variable).

On the other hand, if it truely was an alias, then if it was set to an
expression:
    with c = SumeFuncWithSideEffects(1,2,3) do begin
     c.DoBar;
     c.DoOther;
   end;

should c expand each time, and call the function (with side effects) or should c alias the result. And how could one (as programmer) express, if one wants to allias the function-call (including specific param list), or the result ?

So aliases, if existent could be used in "with" but are not something special to (or limited to) "with". Aliases would be a generic thing (pretty much like "absolute", only they can be set to alias difference things in the code block).

Reply by email

Alexander Klenin
to Martin
Martin wrote 18 lines
IF something like alias were to be introduced (and I am *not* for this), then pascal style, with a declaration above the code. It could then be used in a "with" statement, or anywhere else. procedure foo; var ?c: TObject; alias; begin OR procedure foo; alias ?c: TObject; begin and then ?with c = SomeFoo do c.DoBar

That would defeat the whole purpose of the aliases vs variables, which is to avoid junk declaration.

Of course, the question is why? IT had to be defined where the difference to a normal variable is?

Aliases should not be declared, only defined.

So currently "With" does NOT save a variable (it only saves the reader from spotting the variable).

Of course.

Show quoted text 11 lines
On the other hand, if it truely was an alias, then if it was set to an expression: ? with c = SumeFuncWithSideEffects(1,2,3) do begin ? ?c.DoBar; ? ?c.DoOther; ?end; should c expand each time, and call the function (with side effects) or should c alias the result. And how could one (as programmer) express, if one wants to allias the function-call (including specific param list), or the result ?

Alias should behave like variable (or, rather, constant), except it should not require declaration.

So aliases, if existent could be used in "with" but are not something special to (or limited to) "with". Aliases would be a generic thing (pretty much like "absolute", only they can be set to alias difference things in the code block).

Maybe, but the difference between

  with a := MuFunc do begin .. end;

and

  alias a := MuFunc;

is that in the former case the scope of the alias is explicitly limited to the 'with' statement,
which I think better suits Pascal style (and also has very good analogy to the 'let' statement in Haskell and other functional languages).

As an aside, note that using "=" instead of ":=" is impossible due to
syntax ambiguity -- "with a = b do" is already a valid syntax.
Alexander S. Klenin

Reply by email

Hans-Peter Diettrich
to Michael Schnell: ..and AFAIK using "absolute" is depreciated (at least with Delphi). -Michael
On 08/04/2011 08:12 AM, Sven Barth wrote: > "absolute" is another example of such a construc ..and AFAIK using "absolute" is depreciated (at least with Delphi).

"absolute" is undocumented in XE, but not flagged as deprecated by the compiler. And it works as expected, of course :-)

I mostly use it like Graeme does, with stupid parameter types. But it could be replaced by an additional assignment in the code, of course.

DoDi

Reply by email

Sven Barth
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 10 lines
Michael Schnell schrieb: > On 08/04/2011 08:12 AM, Sven Barth wrote: >> "absolute" is another example of such a construc > ..and AFAIK using "absolute" is depreciated (at least with Delphi). "absolute" is undocumented in XE, but not flagged as deprecated by the compiler. And it works as expected, of course :-) I mostly use it like Graeme does, with stupid parameter types. But it could be replaced by an additional assignment in the code, of course.

Don't you mean "like Sven does"? :P

Regards,
Sven

Reply by email

Lukasz Sokol
to Alexander Klenin: That would defeat the whole purpose of the aliases vs variables, which is to avoid junk…

On 04/08/2011 14:52, Alexander Klenin wrote:
[...]

My thoughts exactly! :)

How about some explicit syntax sugar to help Code Tools understand this construct?

e.g. that an alias can only be declared within the with statement: (and of course the whole alias business can be optional)

with MyLongAndComplicatedObject [as a[:optional type declaration]]
     [,optionally repeated for more aliases] do
begin // 'a' can only be used as alias if not defined in header, error if it does
  // without type declaration you get
  a.Foo; // MyLongAndComplicatedObject.Foo;
  // with type declaration, you get a cast:
  a.Bar; // TFoo(MyLongAndComplicatedObject).Foo;
end;  // scope of 'a' ends here

Hm?

L.

Reply by email

Alexander Klenin
to Lukasz Sokol
Lukasz Sokol wrote 6 lines
On 04/08/2011 14:52, Alexander Klenin wrote: ?e.g. that an alias can only be declared within the with statement: (and of course the whole alias business can be optional) with MyLongAndComplicatedObject [as a[:optional type declaration]] ? ? [,optionally repeated for more aliases] do
"as" creates an ambiguity with existing dynamic casting syntax.
I have really chosen ":=" for a reason ;-)
Show quoted text 9 lines
begin // 'a' can only be used as alias if not defined in header, error if it does ?// without type declaration you get ?a.Foo; // MyLongAndComplicatedObject.Foo; ?// with type declaration, you get a cast: ?a.Bar; // TFoo(MyLongAndComplicatedObject).Foo; end; ?// scope of 'a' ends here

Again, if you add type declaration, it is undistinguishable from the local variable,
so I think it is unnecesary addition.

Alexander S. Klenin

Reply by email

Luca Olivetti
to Lukasz Sokol: Except that in the with construct the named alias will not be an instance of variable,…

Al 03/08/11 17:08, En/na Lukasz Sokol ha escrit:

Show quoted text 8 lines
Except that in the with construct the named alias will not be an instance of variable, but rather a way of _naming_ it shorter, an _alias_; I agree that making it a variable will create all sorts of problems regarding memory management, lifetime management and so on; but the named alias would only live in the block following the with, and could be forced to be strong-typed too. Think plaintext substitution before compilation...

And it's not a new idea either: texas instruments' pascal for the 9995 had it

(though it was 20 years ago and I don't remember the exact syntax, I think it was

  with a=some.structure,b=some.other.structure do

instead of

  with a:=some.structure,b:=some.other.structure

but my memory could be wrong).

I use "with" all the time and I miss that feature (though at the time an edit,compile,link,burn the eprom cycle took half a day, so it was more needed then than it is now).

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email

Sven Barth
to Luca Olivetti
Luca Olivetti wrote 22 lines
Al 03/08/11 17:08, En/na Lukasz Sokol ha escrit: > > Except that in the with construct the named alias will not be an > instance of variable, but rather a way of _naming_ it shorter, an _alias_; > I agree that making it a variable will create all sorts of problems > regarding memory management, lifetime management and so on; but > the named alias would only live in the block following the > with, and could be forced to be strong-typed too. Think plaintext substitution > before compilation... And it's not a new idea either: texas instruments' pascal for the 9995 had it (though it was 20 years ago and I don't remember the exact syntax, I think it was with a=some.structure,b=some.other.structure do instead of with a:=some.structure,b:=some.other.structure but my memory could be wrong).

Well... if another Pascal dialect had it the changes might be higher that it gets integrated into FPC.

So it might be useful to research the exact with syntax of Texas Instruments' Pascal.

Regards,
Sven

Reply by email

Max Vlasov
to Sven Barth
Sven Barth wrote 24 lines
Am 05.08.2011 11:23, schrieb Luca Olivetti: (though it was 20 years ago and I don't remember the exact syntax, I think > it was > > with a=some.structure,b=some.other.**structure do > > instead of > > with a:=some.structure,b:=some.**other.structure > > but my memory could be wrong). > Well... if another Pascal dialect had it the changes might be higher that it gets integrated into FPC. So it might be useful to research the exact with syntax of Texas Instruments' Pascal. Regards, Sven

Luca shared an interesting fact, so I tried to find more information. He probably meant UCSD Pascal, as I see this is a very interesting system, mentioned also in the lazarus wiki (
http://wiki.freepascal.org/UCSD_Pascal). I downloaded the sources of the system, but I could not find the
examples of similar syntax inside many with statements... Maybe there are other sources.

But during the research another interesting specie was found. It's called Sun Workshop Pascal Compiler

http://www.informatik.uni-hamburg.de/RZ/software/SUNWspro/pascal/user_guide/index.html

It supports (supported) standard pascal, with some extensions, that is made to several language constructions including 'with' So on the page

http://www.informatik.uni-hamburg.de/RZ/software/SUNWspro/pascal/lang_ref/ref_state.doc.html

you can see the following example

    with new_patient: new, old_patient: old do begin
      new.LastName := 'Smith';
      new.FirstName := 'Abby';
      new.Sex := Female;
      old.LastName := 'Brown';
      old.FirstName := 'Henry';
      old.Sex := Male
    end;

Using ':' looks a little strange, but at least it worked and probably didn't conflict with existing syntax.

Max
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110805/613381c6/attachment.html>

Reply by email

Luca Olivetti
to Max Vlasov

Al 05/08/11 12:11, En/na Max Vlasov ha escrit:

Luca shared an interesting fact, so I tried to find more information. He probably meant UCSD Pascal, as I see this is a very interesting system, mentioned also in the lazarus wiki ( http://wiki.freepascal.org/UCSD_Pascal ). I downloaded the sources of the system, but I could not find the examples of similar syntax inside many with statements... Maybe there are other sources.

No, I meant TI Pascal.
Since this is very old stuff, I didn't think I could find anything about it, but here is the manual (I'm not sure is the same version I used but it seems pretty close):

http://www.bitsavers.org/pdf/ti/990/pascal/0946290-9701_TI_Pascal_UsersManual_Jan79.pdf

(warning: 34MB file)

On page 62 there's the definition of the with statement and it uses "="

<with statement> ::= WITH <with variable list> DO <statement>
<with variable list> ::= <with variable> {, <with variable>}
<with variable> ::= <record variable> | <identifier> = <record variable>

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email

Sven Barth
to Luca Olivetti
Luca Olivetti wrote 18 lines
Al 05/08/11 12:11, En/na Max Vlasov ha escrit: > Luca shared an interesting fact, so I tried to find more information. He probably meant UCSD Pascal, as I see this is a very interesting system, mentioned also in the lazarus wiki ( http://wiki.freepascal.org/UCSD_Pascal ). I downloaded the sources of the system, but I could not find the examples of similar syntax inside many with statements... Maybe there are other sources. No, I meant TI Pascal. Since this is very old stuff, I didn't think I could find anything about it, but here is the manual (I'm not sure is the same version I used but it seems pretty close): http://www.bitsavers.org/pdf/ti/990/pascal/0946290-9701_TI_Pascal_UsersManual_Jan79.pdf (warning: 34MB file) On page 62 there's the definition of the with statement and it uses "=" <with statement> ::= WITH<with variable list> DO<statement> <with variable list> ::=<with variable> {,<with variable>} <with variable> ::=<record variable> |<identifier> =<record variable>

The internet is a never forgiving source of information ^^

Though "=" seems a little bit like a misuse of that operator... ":="
might be a more pascalish solution.

Thank you for looking.

Regards,
Sven

Reply by email

Luca Olivetti
to Luca Olivetti: Al 05/08/11 12:11, En/na Max Vlasov ha escrit: No, I meant TI Pascal. Since this is very…

Al 05/08/11 12:30, En/na Luca Olivetti ha escrit:

Show quoted text 18 lines
Al 05/08/11 12:11, En/na Max Vlasov ha escrit: > Luca shared an interesting fact, so I tried to find more information. He probably meant UCSD Pascal, as I see this is a very interesting system, mentioned also in the lazarus wiki ( http://wiki.freepascal.org/UCSD_Pascal ). I downloaded the sources of the system, but I could not find the examples of similar syntax inside many with statements... Maybe there are other sources. No, I meant TI Pascal. Since this is very old stuff, I didn't think I could find anything about it, but here is the manual (I'm not sure is the same version I used but it seems pretty close): http://www.bitsavers.org/pdf/ti/990/pascal/0946290-9701_TI_Pascal_UsersManual_Jan79.pdf (warning: 34MB file) On page 62 there's the definition of the with statement and it uses "=" <with statement> ::= WITH <with variable list> DO <statement> <with variable list> ::= <with variable> {, <with variable>} <with variable> ::= <record variable> | <identifier> = <record variable>

This "Student guide" it's also interesting, since it states the differences between standard pascal and TI Pascal:

http://www.bitsavers.org/pdf/ti/990/pascal/pascalStudentGuide_1979.pdf

(warning: 7.8MB file, pages 27-28, "Extended form of the WITH statement")

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email

Sven Barth
to Max Vlasov: Luca shared an interesting fact, so I tried to find more information. He probably meant…
Max Vlasov wrote
But during the research another interesting specie was found. It's called Sun Workshop Pascal Compiler http://www.informatik.uni-hamburg.de/RZ/software/SUNWspro/pascal/user_guide/index.html

It's amazing how many Pascal compilers are out there...

Show quoted text 18 lines
It supports (supported) standard pascal, with some extensions, that is made to several language constructions including 'with' So on the page http://www.informatik.uni-hamburg.de/RZ/software/SUNWspro/pascal/lang_ref/ref_state.doc.html you can see the following example with new_patient: new, old_patient: old do begin new.LastName := 'Smith'; new.FirstName := 'Abby'; new.Sex := Female; old.LastName := 'Brown'; old.FirstName := 'Henry'; old.Sex := Male end; Using ':' looks a little strange, but at least it worked and probably didn't conflict with existing syntax.

Not only the ":" look a bit strange (it remembers me a bit of the on-clause in except blocks though), but also - and more importantly - the order: first the variable or expression that is to be "shortened" and then the new identifier for it.

Regards,
Sven

Reply by email

Luca Olivetti
to Sven Barth: The internet is a never forgiving source of information ^^ Though "=" seems a little bit…

Al 05/08/11 12:40, En/na Sven Barth ha escrit:

Though "=" seems a little bit like a misuse of that operator... ":=" might be a more pascalish solution.

I really don't mind one way or the other, but since a bare = is used for defining constants, it doesn't seem out of place for defining an alias (this is not an assignment).

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email

Alexander Klenin
to Luca Olivetti
Luca Olivetti wrote 7 lines
Al 05/08/11 12:40, En/na Sven Barth ha escrit: > Though "=" seems a little bit like a misuse of that operator... ":=" might be a more pascalish solution. I really don't mind one way or the other, but since a bare = is used for defining constants, it doesn't seem out of place for defining an alias (this is not an assignment).

Unfortunately, "with a = b do" is already a valid operator in FPC, with different meaning.

Alexander S. Klenin

Reply by email

Luca Olivetti
to Alexander Klenin

Al 05/08/11 12:53, En/na Alexander Klenin ha escrit:

Show quoted text 11 lines
On Fri, Aug 5, 2011 at 21:51, Luca Olivetti wrote: > Al 05/08/11 12:40, En/na Sven Barth ha escrit: > >> Though "=" seems a little bit like a misuse of that operator... ":=" might be a more pascalish solution. > > I really don't mind one way or the other, but since a bare = is used for defining constants, > it doesn't seem out of place for defining an alias (this is not an assignment). > Unfortunately, "with a = b do" is already a valid operator in FPC, with different meaning.

What does it mean?

I tried

procedure Test;
 type tr = record
             f1,f2:integer;
           end;
 var r:tr;
begin
  with a=r do;
end;

and trying to compile it
"Error: Operator is not overloaded"
"Error: Expression type must be class or record type"

Same error even if I define a:tr.

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email

Mark Morgan Lloyd
to Alexander Klenin: Unfortunately, "with a = b do" is already a valid operator in FPC, with different meaning.
Alexander Klenin wrote 10 lines
On Fri, Aug 5, 2011 at 21:51, Luca Olivetti wrote: > Al 05/08/11 12:40, En/na Sven Barth ha escrit: > >> Though "=" seems a little bit like a misuse of that operator... ":=" might be a more pascalish solution. > I really don't mind one way or the other, but since a bare = is used for defining constants, > it doesn't seem out of place for defining an alias (this is not an assignment). > Unfortunately, "with a = b do" is already a valid operator in FPC, with different meaning.

In that case use with const which is similar to function declarations.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Hans-Peter Diettrich
to Sven Barth: It's amazing how many Pascal compilers are out there... Not only the ":" look a bit…
> you can see the following example > > with new_patient: new, old_patient: old do begin > new.LastName := 'Smith';

[...]

Not only the ":" look a bit strange (it remembers me a bit of the on-clause in except blocks though), but also - and more importantly - the order: first the variable or expression that is to be "shortened" and then the new identifier for it.

This IMO is due to LL(1), where optional parts deserve a characteristic prefix, which can be combined easily with a separator token. Above snippet would read much more strange as e.g.

       with :new new_patient, :old old_patient do begin

It might look clearer as

       with new_patient as new, old_patient as old do begin

but most probably the "as" was not already a recognized token in that language.

DoDi

Reply by email

Alexander Klenin
to Luca Olivetti: Al 05/08/11 12:53, En/na Alexander Klenin ha escrit: What does it mean? I tried procedure…
Luca Olivetti wrote 21 lines
> Unfortunately, "with a = b do" is already a valid operator in FPC, > with different meaning. What does it mean? I tried procedure Test; ?type tr = record ? ? ? ? ? ? f1,f2:integer; ? ? ? ? ? end; ?var r:tr; begin ?with a=r do; end; and trying to compile it ?"Error: Operator is not overloaded" ?"Error: Expression type must be class or record type" Same error even if I define a:tr.

I thought that you could overload opertator =:

type T = record  x, y: Integer; end;
operator =(A, B: T): T; begin Result := a; end;
var a, b: T;
begin
  with a = b do Writeln(x);
end.

However, FPC forbids overloading of "=" with non-Boolean result, so it turns out you are right, "=" token is available.

Alexander S. Klenin

Reply by email

Robin Hoo
to Alexander Klenin

As I see if we could use with like below, adding a dot before property/function/procedure

with Canvas do
  begin
      .Rectangle(0, 0, .Width, .Height);
  end;

2011/8/5 Alexander Klenin

Show quoted text 44 lines
On Fri, Aug 5, 2011 at 22:04, Luca Olivetti wrote: >> Unfortunately, "with a = b do" is already a valid operator in FPC, >> with different meaning. > > What does it mean? > > I tried > > procedure Test; > type tr = record > f1,f2:integer; > end; > var r:tr; > begin > with a=r do; > end; > > and trying to compile it > "Error: Operator is not overloaded" > "Error: Expression type must be class or record type" > > Same error even if I define a:tr. I thought that you could overload opertator =: type T = record x, y: Integer; end; operator =(A, B: T): T; begin Result := a; end; var a, b: T; begin with a = b do Writeln(x); end. However, FPC forbids overloading of "=" with non-Boolean result, so it turns out you are right, "=" token is available. -- Alexander S. Klenin -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110809/ee10dcef/attachment.html>

Reply by email

David Copeland
to Robin Hoo

Hi,

Can anyone think of a reason why TDateEdit would stop working in an application when thay were working before. There are several TDateEdit's on several forms and they all have stopped responding. If I click on the form background the DateEdit will close. If I try to manually enter the date into the edit box it also appears that the DateOrder is not respected. I am using YMd, but when I try to enter "2011-08-30", the cursor skips to the month when the first "1" in the year is pressed. I update from SVN periodically. This app uses GTK2. If I rebuild the app using QT the TDateEdit's work fine. Also, when I create a new test app with just a TDateEdit using GTK2, it works properly. I'm probably missing something simple, but can't see what it is.

My environment is: Linux Opensuse 11.4, svn revision 31916, FPC 2.4.2.

Thanks,
Dave Copeland.

Reply by email

David Copeland

Apologies to all for mis-posting my last message, I realize now how it happened. Re-posted (hopefully in a new thread).

Hi,

Can anyone think of a reason why TDateEdit would stop working in an application when thay were working before. There are several TDateEdit's on several forms and they all have stopped responding. If I click on the form background the DateEdit will close. If I try to manually enter the date into the edit box it also appears that the DateOrder is not respected. I am using YMd, but when I try to enter "2011-08-30", the cursor skips to the month when the first "1" in the year is pressed. I update from SVN periodically. This app uses GTK2. If I rebuild the app using QT the TDateEdit's work fine. Also, when I create a new test app with just a TDateEdit using GTK2, it works properly. I'm probably missing something simple, but can't see what it is.

My environment is: Linux Opensuse 11.4, svn revision 31916, FPC 2.4.2.

Thanks,
Dave Copeland.

Reply by email

Gerard Visent
to David Copeland

Hi David,

There are several TDateEdit's

on several forms and they all have stopped responding. If I click on the form background the DateEdit will close.

This may be due to the following change, made in mid-july: http://bugs.freepascal.org/view.php?id=14059
See also http://bugs.freepascal.org/view.php?id=14058 In GTK2, the calendar was shown in a modal form and the underlying form wouldn't get the focus until it was closed.
Clicking anywhere outise the calendar now closes it, and it's consistent with what it does under Windows.

If I try to manually enter the date into the edit box it also appears that the DateOrder is not respected. I am using YMd, but when I try to enter "2011-08-30", the cursor skips to the month when the first "1" in the year is pressed.

This works for me (Linux Mint 64 bits, SVN 31924 FPCO 2.4.2).

Show quoted text 6 lines
I update from SVN periodically. This app uses GTK2. If I rebuild the app using QT the TDateEdit's work fine. Also, when I create a new test app with just a TDateEdit using GTK2, it works properly. I'm probably missing something simple, but can't see what it is.

Sorry, no idea of what can be wrong.

Regards,

Gerard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20110809/e309a13a/attachment.html>

Reply by email

David Copeland
to Gerard Visent

Hi Gerard,

Ok, thanks for the idea.

Dave.

Gerard Visent wrote 46 lines
Hi David, There are several TDateEdit's on several forms and they all have stopped responding. If I click on the form background the DateEdit will close. This may be due to the following change, made in mid-july: http://bugs.freepascal.org/view.php?id=14059 See also http://bugs.freepascal.org/view.php?id=14058 In GTK2, the calendar was shown in a modal form and the underlying form wouldn't get the focus until it was closed. Clicking anywhere outise the calendar now closes it, and it's consistent with what it does under Windows. If I try to manually enter the date into the edit box it also appears that the DateOrder is not respected. I am using YMd, but when I try to enter "2011-08-30", the cursor skips to the month when the first "1" in the year is pressed. This works for me (Linux Mint 64 bits, SVN 31924 FPCO 2.4.2). I update from SVN periodically. This app uses GTK2. If I rebuild the app using QT the TDateEdit's work fine. Also, when I create a new test app with just a TDateEdit using GTK2, it works properly. I'm probably missing something simple, but can't see what it is. Sorry, no idea of what can be wrong. Regards, Gerard. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

David Copeland
to David Copeland

I have reverted to svn 31555, a revision prior to this change, and the calendar now responds as expected,

Dave.

David Copeland wrote 63 lines
Hi Gerard, Ok, thanks for the idea. Dave. On Tue, 2011-08-09 at 18:39 +0200, Gerard Visent wrote: > Hi David, > > There are several TDateEdit's > on several forms and they all have stopped responding. If I > click on the > form background the DateEdit will close. > > This may be due to the following change, made in mid-july: > http://bugs.freepascal.org/view.php?id=14059 > See also http://bugs.freepascal.org/view.php?id=14058 > In GTK2, the calendar was shown in a modal form and the underlying > form wouldn't get the focus until it was closed. > Clicking anywhere outise the calendar now closes it, and it's > consistent with what it does under Windows. > > If I try to manually enter the > date into the edit box it also appears that the DateOrder is > not > respected. I am using YMd, but when I try to enter > "2011-08-30", the > cursor skips to the month when the first "1" in the year is > pressed. > > This works for me (Linux Mint 64 bits, SVN 31924 FPCO 2.4.2). > > I > update from SVN periodically. This app uses GTK2. If I rebuild > the app > using QT the TDateEdit's work fine. Also, when I create a new > test app > with just a TDateEdit using GTK2, it works properly. I'm > probably > missing something simple, but can't see what it is. > > Sorry, no idea of what can be wrong. > > Regards, > > Gerard. > > > -- > _______________________________________________ > Lazarus mailing list > > http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Maxim Ganetsky
to David Copeland: Apologies to all for mis-posting my last message, I realize now how it happened.…

09.08.2011 16:23, David Copeland ?????:

Show quoted text 16 lines
Apologies to all for mis-posting my last message, I realize now how it happened. Re-posted (hopefully in a new thread). Hi, Can anyone think of a reason why TDateEdit would stop working in an application when thay were working before. There are several TDateEdit's on several forms and they all have stopped responding. If I click on the form background the DateEdit will close. If I try to manually enter the date into the edit box it also appears that the DateOrder is not respected. I am using YMd, but when I try to enter "2011-08-30", the cursor skips to the month when the first "1" in the year is pressed. I update from SVN periodically. This app uses GTK2. If I rebuild the app using QT the TDateEdit's work fine. Also, when I create a new test app with just a TDateEdit using GTK2, it works properly. I'm probably missing something simple, but can't see what it is.

Please create a bug report, attach to it small test project and detailed description what doesn't work and what is expected.

Best regards, Maxim Ganetsky mailto:

Reply by email

Felipe Monteiro de Carvalho
to Maxim Ganetsky
Maxim Ganetsky wrote
Please create a bug report, attach to it small test project and detailed description what doesn't work and what is expected.

And please write in the title of the bug report the word "regression"

Felipe Monteiro de Carvalho

Reply by email

David Copeland
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 6 lines
On Tue, Aug 9, 2011 at 9:58 PM, Maxim Ganetsky wrote: > Please create a bug report, attach to it small test project and detailed > description what doesn't work and what is expected. And please write in the title of the bug report the word "regression"

Will do. However, the small test project I created to illustrate the problem, failed to do so, ie. the DateEdit worked ok. Since main app is too large to send I will have to do some more investigation to recreate the problem in the test project.

Reply by email