Anders Melander 1783 Posted May 15, 2020 3 minutes ago, Bernard said: Is this different than Classes with forward declarations? Classes are reference types. Share this post Link to post
Bernard 18 Posted May 15, 2020 1 hour ago, Anders Melander said: Classes are reference types. I get it now. Share this post Link to post
Remy Lebeau 1396 Posted May 15, 2020 11 hours ago, Bernard said: Is this different than Classes with forward declarations? Classes are reference types in Delphi: "Reference types can be forward declared because their size are always known (=SizeOf(pointer))." Share this post Link to post
Vandrovnik 214 Posted May 16, 2020 If size was the only problem, I can imagine something like this ("human preprocessor"): type tRecordA = record of size 8; tRecordB = record ... function Test: tRecordA; end; tRecordA = record x, y: integer; end; Share this post Link to post
Anders Melander 1783 Posted May 16, 2020 5 hours ago, Vandrovnik said: If size was the only problem It isn't. The type and offset of the members needs to be known too: type TMyRecord = record Foo: integer; Bar: string; end; TMyClass = class private FFooBar: TMyRecord; public property Foo: integer read FFooBar.Foo; property Bar: string read FFooBar.Bar; end; Share this post Link to post
David Heffernan 2345 Posted May 16, 2020 55 minutes ago, Anders Melander said: It isn't. The type and offset of the members needs to be known too: type TMyRecord = record Foo: integer; Bar: string; end; TMyClass = class private FFooBar: TMyRecord; public property Foo: integer read FFooBar.Foo; property Bar: string read FFooBar.Bar; end; If what you say were true, then class forward references would not exist. Share this post Link to post
Vandrovnik 214 Posted May 16, 2020 12 minutes ago, David Heffernan said: If what you say were true, then class forward references would not exist. I believe Anders is right. Class reference is just a pointer - its size is known. When you use this class as a member of another class (fChild: tChild, where tChild is a class), you cannot reference its members in properties (property x: integer read fChild.x). If fChild is a record (fChild: tChild, where tChild is a record), you can reference its members in properties, like in Anders' example (property x: integer read fChild.x). Share this post Link to post
David Heffernan 2345 Posted May 16, 2020 33 minutes ago, Vandrovnik said: I believe Anders is right. Class reference is just a pointer - its size is known. When you use this class as a member of another class (fChild: tChild, where tChild is a class), you cannot reference its members in properties (property x: integer read fChild.x). If fChild is a record (fChild: tChild, where tChild is a record), you can reference its members in properties, like in Anders' example (property x: integer read fChild.x). Not being able to do that one thing would hardly invalidate the entire enterprise. We'd still be able to use the type as procedure argument which is the main thing we are striving for. But the whole argument is predicted on this single pass. It's no big deal to pass over each type section twice to process forward declarations. Won't make a blind bit of difference to performance. Bottom line is that it is perfectly possible to do this if Emba wanted to. Share this post Link to post
Anders Melander 1783 Posted May 16, 2020 2 hours ago, David Heffernan said: Won't make a blind bit of difference to performance. Not in this single case, I agree, but beware of tunnel vision. Regardless the obstacle is probably more a question of resources and priorities. It might also not be easy to shoehorn something like this into the existing compiler. If it's implemented like a traditional one-pass compiler it will be using various optimizations that can only be made because it's a one-pass compiler. Share this post Link to post
David Heffernan 2345 Posted May 16, 2020 11 minutes ago, Anders Melander said: Regardless the obstacle is probably more a question of resources and priorities. This is the point that I've been making all along. 1 Share this post Link to post
Marat1961 17 Posted November 25, 2020 I certainly understand that many people did not program on a pure Pascal. Use pointers and you will be happy. Pointers to a record can be declared before the record is declared. Also if you pass a record as a parameter, there is no need to pass the value as it is extremely inefficient and the recording value is copied to the stack. Transmit the record by var or by const. PPoint2D = ^tPoint2D; Share this post Link to post
Marat1961 17 Posted November 25, 2020 (edited) On 5/13/2020 at 8:16 PM, Bernard said: It would be great with all the record enhancements in the next version to be able to write tPoint2D = record; tPolar2D = record Radius: Double; azimuth: Double; function ToCartesian: tPoint2D; end; tPoint2D = record x: Double; y: Double; function ToPolar: tPolar2D; end; Thanks again for the feedback PPoint2D = ^TPoint2D; PPolar2D = ^TPolar2D; constructor TPolar2D.From(const Pt: PPoint2D); constructor TPolar2D.From(X, Y: Double); constructor TPoint2D.From(const Pt: PPolar2D); constructor TPoint2D.From(Radius, Azimuth: Double); PNode = ^TNode; TNode = record next: PNode; end; var ppt: TPolar2D; cpt: TPoint2D; begin ppt := TPolar2D.From(@cpt); end. Edited November 25, 2020 by Marat1961 Share this post Link to post
Javier Tarí 23 Posted December 1, 2020 On 5/13/2020 at 3:16 PM, Bernard said: It would be great with all the record enhancements in the next version to be able to write tPoint2D = record; tPolar2D = record Radius: Double; azimuth: Double; function ToCartesian: tPoint2D; end; tPoint2D = record x: Double; y: Double; function ToPolar: tPolar2D; end; One possible solution could be allowing a two-phase declaration: tPolar2D = record Radius: Double; azimuth: Double; end; forward; //keyword just to say there are methods to be defined later tPoint2D = record x: Double; y: Double; function ToPolar: tPolar2D; end; tPolar2D = record finalization function ToCartesian: tPoint2D; end; Share this post Link to post
Marat1961 17 Posted December 6, 2020 tPolar2D = record Radius: Double; azimuth: Double; end; forward; //keyword just to say there are methods to be defined later In my opinion, this is not the most successful design. A radical solution is needed. It is much better to add a namespace. And inside the namespace, allow to refer to any declarations, regardless of the order of their declaration. Share this post Link to post