Recent

Author Topic: What is the difference between the new ADVANCED RECORD and the old OBJECT?  (Read 14827 times)

jamie

  • Hero Member
  • *****
  • Posts: 4337
Re: What is the difference between the new ADVANCED RECORD and the old OBJECT?
« Reply #45 on: February 25, 2021, 01:24:35 am »
I wanted to add that recently and still on going, I have taken on the task of converting a C++ over to lazy and of course many of you know that C++ coders just their operators for the classes..

 Well with the pascal objects classes are always dynamic and problematic for operators implementations and then here comes the advanced records where they solve the issue however, classes I am duplicating has many parent classes etc and Advanced records just can't cut the mustered on that one...

 So I found that the object model solves The problem with the operators and I can inherit etc..

One day I may find a way to get the operators to properly address the returning object within instead of it creating a new object which in the case for a class would end up being junk.

 The fix would be to some how make the operator code understand that you need a reference to the returning class object and have not create a stub.

 Its a dream I know but one that may come true.

The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 4337
Re: What is the difference between the new ADVANCED RECORD and the old OBJECT?
« Reply #46 on: February 25, 2021, 03:10:56 am »
I found a hack that works for Classes, not REcords but classes...

The problem is fpc treats operators as functions always and thus if you create an operator that returns a Class it is basically returning junk because it creates a object pointer of junk etc..

 however, if you INLINE a short operator the compiler then puts all the code inline and thus you are dealing with the original object instance and this works however,, it does generate a little bit of overhead so if used a lot then it can create alittle bloat

 So this is what I come up with...

Code: Pascal  [Select][+][-]
  1. Procedure Ox(A:TForm1;Value:Integer);
  2. Begin
  3.  A.Caption := value.Tostring;
  4. End;
  5. operator := (R:Integer):Tform1;inline;
  6. Begin
  7.  Ox(Result,R);
  8. end;                                                
  9.  

and the test code.

Code: Pascal  [Select][+][-]
  1.  Form1 := 1;        
  2.  

The dump code
Code: Pascal  [Select][+][-]
  1. unit1.pas:55                              Form1 := 1;
  2. 000000010002CAD1 488b05084c2b00           mov    0x2b4c08(%rip),%rax        # 0x1002e16e0 <U_$UNIT1_$$_FORM1>
  3. 000000010002CAD8 ba01000000               mov    $0x1,%edx
  4. 000000010002CADD 4889c1                   mov    %rax,%rcx
  5. 000000010002CAE0 e88bffffff               callq  0x10002ca70 <OX>
  6. unit1.pas:56                              end;
  7.  
  8.  

To me that seems to work when results of a operator is a dynamic object..
what do you think ?

The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 4337
Re: What is the difference between the new ADVANCED RECORD and the old OBJECT?
« Reply #47 on: February 25, 2021, 05:08:46 am »
I wanted to let everyone know that this code only works with 3.0.4 and down..

I found a bug in the 3.2.0 compiler, it forgets to inject the first line of ASM code that is needed when doing the INLINE ..
Code: Pascal  [Select][+][-]
  1.  
  2. unit1.pas:55                              Form1 := 1;
  3. 000000010002CAD1 488b05084c2b00           mov    0x2b4c08(%rip),%rax        # 0x1002e16e0 <U_$UNIT1_$$_FORM1>
  4. 000000010002CAD8 ba01000000               mov    $0x1,%edx
  5. 000000010002CADD 4889c1                   mov    %rax,%rcx
  6. 000000010002CAE0 e88bffffff               callq  0x10002ca70 <OX>
  7. unit1.pas:56                              end;
  8.  

The very first line of ASM code Is missing with the 3.2.0.

Its a bad move on the compiler..

I now know what is wrong with a project that compiles a DLL incorrectly using 3.2.0 because I use such code like this , lots of Inlines and I just checked it, yes it forgets to insert some code..

This DLL I am talking about is still compiled with 3.0.4. as this test app is too and it works..
so I guess I'll need to stick with a 3.0.4 Lazarus install for now..
The only true wisdom is knowing you know nothing

ASBzone

  • Hero Member
  • *****
  • Posts: 595
  • Automation leads to relaxation...
    • Free Console Utilities for Windows (and a few for Linux) from BrainWaveCC
The very first line of ASM code Is missing with the 3.2.0.

Hey, @jamie.  The two asm snippets you posted, one for 3.0.4 and one for 3.2.0, appear to be identical.
-ASB: https://www.BrainWaveCC.com/

Lazarus v2.0.13 r64843 / FPC v3.2.1-r49055 (via FpcUpDeluxe) -- Windows 64-bit install w/Win32 and Linux/Arm cross-compiles
Primary System: Windows 10 Pro x64, Version 2009 (Build 19042)
Other Systems: Windows 10 Pro x64, Version 2009 (Build 19042) or greater

jamie

  • Hero Member
  • *****
  • Posts: 4337
I did not post the 3.2.0 output here. Those are both 3.0.4 64 bit.

What i was saying is the first line of asm that u see there is missing from the 3.2.0 output.

And because of that the inline proxy over to a procedure fails with 3.2.0

No worries , i moved that project to delphi and most likely will do the same for others when 3.0.4 goes dead
The only true wisdom is knowing you know nothing

Blade

  • Jr. Member
  • **
  • Posts: 73
First there were record, procedures and functions.
Next, with the emergence of OOP, there were objects.
Next, Borland has introduced classes in which there are additional opportunities. And to force everyone to switch to a new way of declaration, a objects was sign as deprecated.
Later, when it was necessary to merge fields and methods again, it was already inconvenient to revive objects declared as deprecated. And decided to expand records.
And, accordingly, all the new features have tried to do only for records, skipping the implementation for objects, so that they correspond to the previously established policy. And either intentionally made mistakes in the support of old objects, or rather greatly inflated random errors to convince not to use objects.

The classes concept already existed in the Clascal language for Apple's Lisa computer (the earliest object-oriented Pascal dialect), but it was abandoned by Larry Tesler after being advised by Niklaus Wirth. Later, classes were reintroduced by Borland for Delphi.

True, in terms of Class-based OOP.  Clascal was a play on words, "Pascal with classes".  Kind of like the supposedly original name of C++, C with classes.  But, it arguably should not be ignored that many programmers and programming languages have used objects without classes.  Some examples of this are JavaScript and Lua, which are Prototype-based OOP languages, and newer languages like Go (Golang) which avoids Class-based OOP.  In many cases and other languages, people often just want extensible associative arrays and the convenience of dot notation, not the baggage of Class-based OOP.

To add to the fun, there is of course C and structs, but arguments on whether or not that can even be considered OO (or can be implemented like such) can make you dizzy, often the arguments center around if having objects without methods and/or classes is really OOP.  Arguments along those lines can become quite philosophical, where people believe that nouns and verbs (data and functions) should remain separate from each other.  Additionally, you can have objects without classes that are data only, inherit, and/or are encapsulated, but the implementation becomes a sticking point.  There are competing views as to what exactly OO is.

Be that as it may, clearly there is a place for the "plain" object concept or a simpler implementation of OO that is not so class-centric.  I think a reflection of such is why we have this interesting juggling of advanced records, objects, and classes in our language.  I think people have different comfort levels and views about how deep to go or how often they need Class-based OOP.  The great thing about Object Pascal/Free Pascal, is that as a hybrid language, we have options.  Arguably, OOP is done more gently and optionally in our language.
« Last Edit: March 23, 2021, 02:17:00 pm by Blade »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 9192
  • FPC developer.
  In many cases and other languages, people often just want extensible associative arrays and the convenience of dot notation, not the baggage of Class-based OOP.

Dot notation vs -> is a C++ problem. It doesn't have anything to do with class based OOP, since the language can just autoderef, like many languages do (include FPC in some modes)

Quote
Be that as it may, clearly there is a place for the "plain" object concept or a simpler implementation of OO that is not so class-centric. 

The trouble is that for that small class of cases you either have to have a lot of explicit reference usage around it (like in C++ but I assume that could also be done smarter) or have two OO models.

Neither is a very attractive solution. Moreover we already have 5MLoc of class based code.

Blade

  • Jr. Member
  • **
  • Posts: 73
Quote
Be that as it may, clearly there is a place for the "plain" object concept or a simpler implementation of OO that is not so class-centric. 
Quote
The trouble is that for that small class of cases you either have to have a lot of explicit reference usage around it (like in C++ but I assume that could also be done smarter) or have two OO models.

Neither is a very attractive solution. Moreover we already have 5MLoc of class based code.

I have a tremendous amount of respect and empathy for developers, and I'm quite sure two OO models is not something that many would find agreeable.  In fact, I'm at peace with how Class-based OOP was implemented in Free Pascal/Delphi. 

But, it doesn't change the fact that other languages took different paths and it's working for them or that many programmers are not comfortable with the conventional implementations of Class-based OOP, having fragmented data merged with methods (the nouns should be separated from verbs debate), or with particular pillars of OOP like inheritance (which also gets into the composition versus inheritance debates) and encapsulation.  Even the creator of Pascal (Niklaus Wirth) appeared to give some push back on the various pillars and use cases of conventional OOP, where they can be different useful alternatives in various situations.  Of course in certain cases, the full glory of Class-based OOP (with inheritance, encapsulation, polymorphism, etc...) is exactly the right answer.  Just not always the answer.

In Object Pascal circles, it appears that records and advanced records are kind of like viable alternatives.  If you look at many of the criticisms of conventional OOP, you can see that records and advances records can also be a way to provide more philosophically agreeable alternatives to many.  That is: you can separate nouns from verbs (unwanted coupling of fragmented data with methods/among multiple classes), choose composition over inheritance (or choose explicit inheritance with records when wanted), rely more on using units as way to extend program functionality, a reduction in Class-based OOP specific syntax/keeping smaller programs simple, easier troubleshooting, etc... As for "old school Objects", arguably they can be seen as a simpler way to deal with OOP or offer some specifically wanted advantage.

I'm of the opinion that the situation works for many Object Pascal programmers, where they can choose suitable options of their liking.  Definitely not saying that such a situation would be viewed as optimal by most developers (who are looking at things at a larger scale than most), but forcing only a certain path might not be helpful to many either.  Perhaps that's partly how Borland/Embarcadero put Delphi into a messy situation with advanced records and their implementations of OOP.  Don't see any easy answers.
« Last Edit: March 25, 2021, 03:00:15 pm by Blade »

 

TinyPortal © 2005-2018