Recent

Author Topic: [SOLVED] Using records inside the class  (Read 5749 times)

julkas

  • Guest
[SOLVED] Using records inside the class
« on: April 23, 2019, 08:43:35 pm »
Reading fcl-stl gset implementation on GitHub I found that gset class contains pointer to the record. Why usage of records in the class? Why just not standard class fields?
Code: Pascal  [Select][+][-]
  1. generic TSet<T, TCompare>=class
  2.   public
  3.   type
  4.     PNode=^Node;
  5.     Node=record
  6.       Data:T;
  7.       Left,Right:PNode;
  8.       Parent:PNode;
  9.       Color:boolean;
  10.     end;
  11.     TIterator=specialize TSetIterator<T, Node>;
  12.   var
  13.   private
  14.     FBase:PNode;
  15.     FSize:SizeUInt;

BTW FSize is outside the record!

Thanks.
« Last Edit: April 24, 2019, 07:19:22 pm by julkas »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Using records inside the class
« Reply #1 on: April 23, 2019, 11:06:49 pm »
My guess (and it's just a guess, i've not eye-grepped the code) is it's using a quite standard double-linked list and the implementor found easier to GetMem() for a whole record. I woul probably have the done the same if my surmise is correct.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

ASerge

  • Hero Member
  • *****
  • Posts: 2248
Re: Using records inside the class
« Reply #2 on: April 24, 2019, 12:00:18 am »
I agree with @lucamar. For each element, a record is used, and class fields are used to manage the entire set.

julkas

  • Guest
Re: Using records inside the class
« Reply #3 on: April 24, 2019, 09:25:31 am »
it's using a quite standard double-linked list and the implementor found easier to GetMem() for a whole record.

1. I think OO implementation of standard double-linked list is more readable, extendable and customizable.
2. There must be other reasons (memory, performance,...)
3. Using records in classes in wrong place and way breaks OO spirit and design.

Any idea, thoughts?

Thanks.

Thaddy

  • Hero Member
  • *****
  • Posts: 14381
  • Sensorship about opinions does not belong here.
Re: Using records inside the class
« Reply #4 on: April 24, 2019, 09:35:41 am »
Any idea, thoughts?
fcl-stl is not exactly the best implementation -its interface is! -. It tries to mimic a C++ style standard template library..
FPC/Lazarus has at least two standard libraries that are - implementation wise - much better:
- fgl
- rtl-generics.

Furthermore these are - but this is my opinion - much easier to use.

People coming from other languages often make the mistake to go for FCL-stl instead of RTL-generics (or for 3.0.4 and before: fgl.) because it contains a magic word: stl. But it should not contain that magic word.
That said: with some effort it could achieve what it advertises.

Quote
1. I think OO implementation of standard double-linked list is more readable, extendable and customizable.
A TList or a TList<T> are underneath linked lists, just like in C.
Quote
2. There must be other reasons (memory, performance,...)
No. The only reasons are OOP in the first place: A linked list isn't. It's a list of pointers, a.k.a. memory locations.
IOW very low-level. OOP is about high-level abstractions.
Quote
3. Using records in classes in wrong place and way breaks OO spirit and design.
You do not understand the encapsulation part of object orientation.
Structures or variables in general can be tightly coupled to a class they belong to.
That's an asset. Not a hindrance.
« Last Edit: April 24, 2019, 09:59:46 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

mas steindorff

  • Hero Member
  • *****
  • Posts: 533
Re: Using records inside the class
« Reply #5 on: April 24, 2019, 09:55:25 am »
I like to use records inside my classes as well for 2 reasons. 

1st it shows a variable that may have a common name is truly the one I have defined in the class (like index or tag... my.index, my.tag) or simply to avoid function call vis var like fileExsit vis my.fileExsit

2nd I may wish to use a property field to limit access to a variable now that I will replace with a set and get function later.  Or I only wish to give it read only access outside the class. In my code I know I will have full access to the core variable so I can read and write it as needed.

Example
...tmyclass = class
... my = record
  Count :int64;
  Index :int64;
...
End ; //of record
Public

Property count :int64 read my.count; 
...
End; //of class
windows 10 &11, Ubuntu 21+ - fpc 3.0.4, IDE 2.0 general releases

Thaddy

  • Hero Member
  • *****
  • Posts: 14381
  • Sensorship about opinions does not belong here.
Re: Using records inside the class
« Reply #6 on: April 24, 2019, 10:01:17 am »
I like to teach whatever my computer science knowledge can bring to other programmers.
That's not perfect, but usually correct.

So, Max you are correct.
« Last Edit: April 24, 2019, 10:04:25 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

julkas

  • Guest
Re: Using records inside the class
« Reply #7 on: April 24, 2019, 10:24:05 am »
fcl-stl is not exactly the best implementation -its interface is! -. It tries to mimic a C++ style standard template library..
FPC/Lazarus has at least two standard libraries that are - implementation wise - much better:
- fgl
- rtl-generics.

OK. My question is not from the user side, but from learner and programmer. I try to understand pros and cons of gset implementation.

Why not simply -

Code: Pascal  [Select][+][-]
  1. generic TSet<T, TCompare>=class
  2.   public
  3.       Data:T;
  4.       Left,Right:TSet;
  5.       Parent:TSet;
  6.       Color:boolean;
  7.       FSize:SizeUInt;
« Last Edit: April 24, 2019, 11:14:25 am by julkas »

Thaddy

  • Hero Member
  • *****
  • Posts: 14381
  • Sensorship about opinions does not belong here.
Re: Using records inside the class
« Reply #8 on: April 24, 2019, 11:50:43 am »
Well, the public part is not immediately correct, if you mean that.
Records declared inside of a class should not have the possibility to be accessed outside of that class or (when protected) outside of inherited classes.

There are cases, though, that warrant it. These are rare.

You are asking the right questions...

Scope is essentially what prevents you from making mistakes.
« Last Edit: April 24, 2019, 12:00:34 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

creaothceann

  • Full Member
  • ***
  • Posts: 117
Re: Using records inside the class
« Reply #9 on: April 24, 2019, 06:48:19 pm »
OO spirit and design
OO is just one tool. Tools are specific to their use cases, and you have to know when to switch tools. There is no silver bullet.

(OO is frequently not used for example in high-performance game programming because OO often groups data unrelated to the current job together, i.e. the fields of an object are all bundled in one memory location, wasting the cache space of modern CPUs.)

mas steindorff

  • Hero Member
  • *****
  • Posts: 533
Re: Using records inside the class
« Reply #10 on: April 24, 2019, 08:09:06 pm »
OK. My question is not from the user side, but from learner and programmer. I try to understand pros and cons of gset implementation.
well, one "pro" to this is by by placing all of my variables in a record, I can use a call to fillchar(my,sizeof(my),0) => "fill memory with 0" in my Clear() procedure. My warning anyone using this trick is you can only have simple variables in your record. Strings, classes, and even arrays defined within the record should not be cleared in this manor so I keep them outside the record.

this trick lets me add more variables and not worry about re-init each one in either the class.create or .clear procedures.

it's also simpler to create a class.Assign().  I can copy all of the variables with a one liner self.my := src.my;  and then go in and modify the ones I need to.   

windows 10 &11, Ubuntu 21+ - fpc 3.0.4, IDE 2.0 general releases

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11455
  • FPC developer.
Re: Using records inside the class
« Reply #11 on: April 24, 2019, 10:56:44 pm »
A TList or a TList<T> are underneath linked lists, just like in C.

Nope, basically just array wrappers.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5486
  • Compiler Developer
Re: [SOLVED] Using records inside the class
« Reply #12 on: April 25, 2019, 12:11:33 pm »
Reading fcl-stl gset implementation on GitHub I found that gset class contains pointer to the record. Why usage of records in the class? Why just not standard class fields?
Code: Pascal  [Select][+][-]
  1. generic TSet<T, TCompare>=class
  2.   public
  3.   type
  4.     PNode=^Node;
  5.     Node=record
  6.       Data:T;
  7.       Left,Right:PNode;
  8.       Parent:PNode;
  9.       Color:boolean;
  10.     end;
  11.     TIterator=specialize TSetIterator<T, Node>;
  12.   var
  13.   private
  14.     FBase:PNode;
  15.     FSize:SizeUInt;

BTW FSize is outside the record!

Thanks.
It seems that you misunderstand what is happening here. Node is not a field, it's a type. It would logically be equal to declare Node outside of TSet<,>. This way TSet<,> can contain multiple Node entries by using a linked list which is much less expensive than doing a linked list for the whole class. And the FSize is simply there to keep track of the amount of items without the need to iterate the whole linked list.

julkas

  • Guest
Re: [SOLVED] Using records inside the class
« Reply #13 on: April 25, 2019, 05:43:59 pm »
It seems that you misunderstand what is happening here. Node is not a field, it's a type. It would logically be equal to declare Node outside of TSet<,>. This way TSet<,> can contain multiple Node entries by using a linked list which is much less expensive than doing a linked list for the whole class. And the FSize is simply there to keep track of the amount of items without the need to iterate the whole linked list.
Ok. Thanks. I got it. I am writing implementation of similar data structure without records. Node is instance of class in my code and all operations are class methods. This approach has overheads, but works good and fast. Gset instance holds only  pointer to the root node.  But my question remains.

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: Using records inside the class
« Reply #14 on: April 25, 2019, 05:52:04 pm »
OK. My question is not from the user side, but from learner and programmer. I try to understand pros and cons of gset implementation.
well, one "pro" to this is by by placing all of my variables in a record, I can use a call to fillchar(my,sizeof(my),0) => "fill memory with 0" in my Clear() procedure. My warning anyone using this trick is you can only have simple variables in your record. Strings, classes, and even arrays defined within the record should not be cleared in this manor so I keep them outside the record.

@mas steindorff:
Look at this thread "Weird Memory Leak!!". Martin_fr suggested to use this code:
Code: Pascal  [Select][+][-]
  1. procedure FillerByte(out x; count: SizeInt; value: byte);
  2. begin
  3.    FillByte(x, count, value);
  4. end;
  5.  
And now I can't live without that code (by the way this month was the birthday of such a great procedure, now it has 7 years and 20 days old  :D )

 

TinyPortal © 2005-2018