Recent

Author Topic: IRC channel  (Read 11081 times)

Joanna

  • Hero Member
  • *****
  • Posts: 724
Re: IRC channel
« Reply #30 on: November 25, 2022, 03:07:14 pm »
Hi Martin
That is some interesting stuff. I vaguely remember being told a long time ago that a parameter without a var would be a copy that could be changed in the body of the procedure but would not be permanent. But var would affect what was being sent directly. The option of the const parameter was never mentioned in beginning pascal class.

Code: Pascal  [Select][+][-]
  1.  procedure bar(c: TFoo);
  2. begin
  3.   c.F1 := 11; // affects the callers instance too / only the pointer is passed in c - it points to the same memory
  4.   c := TFoo.create; // does not affect the caller // new memory, and pointer goes into c
  5. end;
  6.  
  7. procedure xyz(var c: TFoo);
  8. begin
  9.   c.F1 := 11; // affects the callers instance too // affects the data pointed to // does not affect the pointer in c
  10.   c := TFoo.create; // does ALSO affect the caller // because "c" is var. So modifying "c" also modifies the caller
  11. end;

In the last example  it seems it seems like you are detaching the pointer  from c and assigning it to a new location possibly leaving the allocated memory it was pointing to stranded. Does modern pascal have a way to prevent stranded memory that can no longer be accessed? It seems like a memory leak could happen.

Also I’m really not sure how classes are different from objects they both seem to allow the bundling of methods and data. I’m assuming that more can be done with classes. I’ve also noticed that sender is tobject .
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: IRC channel
« Reply #31 on: November 25, 2022, 03:30:27 pm »
"var" is a functional change - It allows to modify the callers value.
"const" is a mere optimization - The programmer tells the compiler, that it can optimize under the assumption that the value wont change (including the callers value)

"record" => memory allocated on the stack (except for global vars). If you leave the procedure the memory is freed (result:record is passed by the caller)
"class" => memory is allocated on the heap (like "new(PMyRecord);" where "PMyRecord = ^TMyRecord")

"type TFoo = object ... end" => an advanced record with some (limited) inheritance

"var a: MyRecord" => a contains the entire record (all the fields). "b:=a" will copy all the fields.
"var a: TMyClass" => a contains the pointer to the memory. "a := b" only copies the pointer.

For a class the value of the variable is the pointer only. That means passing it as const requires just  the pointer to be const. Passing it as "var" affects the pointer.



MyClass.Create is like allocmem (or like "New(PFoo)"). You must ensure yourself that the mem is freed. And also take care that any copies of pointer to that mem are not used after the mem was freed.

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: IRC channel
« Reply #32 on: November 25, 2022, 03:45:44 pm »
Code: Pascal  [Select][+][-]
  1.  procedure bar(c: TFoo);
  2. begin
  3.   c.F1 := 11; // affects the callers instance too / only the pointer is passed in c - it points to the same memory
  4.   c := TFoo.create; // does not affect the caller // new memory, and pointer goes into c [MEMORY LEAK IN THE LOCAL MEMORY]
  5. end;
  6.  
  7. procedure xyz(var c: TFoo);
  8. begin
  9.   c.F1 := 11; // affects the callers instance too // affects the data pointed to // does not affect the pointer in c
  10.   c := TFoo.create; // does ALSO affect the caller // because "c" is var. So modifying "c" also modifies the caller [THIS MAKES A MEMORY LEAK TO THE INCOMING MEMORY]
  11. end;

In the last example  it seems it seems like you are detaching the pointer  from c and assigning it to a new location possibly leaving the allocated memory it was pointing to stranded. Does modern pascal have a way to prevent stranded memory that can no longer be accessed? It seems like a memory leak could happen.

Also I’m really not sure how classes are different from objects they both seem to allow the bundling of methods and data. I’m assuming that more can be done with classes. I’ve also noticed that sender is tobject .
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: IRC channel
« Reply #33 on: November 25, 2022, 04:27:54 pm »
I’ve also noticed that sender is tobject .
TObject is a class.

But the naming is partly messy.

In modern pascal the word (but not keyword) "object" is usually used for "instance of a class". That is the result of "TFooClass.create();"

However we also have the keyword "object" (aka old-style object), which also describes an object. Just a completely different one.
That keyword "object" is rarely used today (since there are advanced records).
There are still differences... Note that those old objects also come with some pitfalls if you use them with inheritance....
(So don't bother about them, just be aware that they exist and therefore the English word "object" is ambiguous)

"keyword object" => the variable (like with a record) does contain all the fields. No memory needs to be allocated (other than that which already is in the variable), and there is no pointer.
So you don't need to "create an instance" (well one could say, you do that by declaring the variable...).


KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: IRC channel
« Reply #34 on: November 25, 2022, 04:39:33 pm »
That keyword "object" is rarely used today (since there are advanced records).
...hmmm... I think I use that "rarely old keyword" in every of my classes when I set up custom event handlers...
And I could lay my hand in fire that everyone that uses OOP do the same, custom or via https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tnotifyevent.html.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: IRC channel
« Reply #35 on: November 25, 2022, 04:53:54 pm »
That keyword "object" is rarely used today (since there are advanced records).
...hmmm... I think I use that "rarely old keyword" in every of my classes when I set up custom event handlers...
And I could lay my hand in fire that everyone that uses OOP do the same, custom or via https://lazarus-ccr.sourceforge.io/docs/rtl/classes/tnotifyevent.html.
Ahhh, yes but no-ish...

"of object" - well yes that is also "object" as keyword.

And yes, originally this (likely) refers to the "type TFoo = object ... end;".
Because indeed a procedure/function from such an old style object can be assigned to an "of object".

Then again, "of object" now also comprises the procedures/functions of a class. (And is more often associated with that, than with the old style object)


The issue is that "class" and instances thereof are objects. But they are not the type "object". The word object is ambiguous.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Re: IRC channel
« Reply #36 on: November 25, 2022, 05:10:56 pm »
The issue is that "class" and instances thereof are objects. But they are not the type "object". The word object is ambiguous.
Agreed  :-*
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Joanna

  • Hero Member
  • *****
  • Posts: 724
Re: IRC channel
« Reply #37 on: November 25, 2022, 11:41:48 pm »
I remember there are two different units classes and objects if I remember correctly that contain things called objects and irs easy to get them mixed up.  declaration in uses section gives one priority. I first discovered objects in turbo pascal I’m guessing those were the old style objects. I really don’t like the naming of “advanced records “ to me a record should contain data and nothing else. I’m not even sure how to declare or use an advanced record.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: IRC channel
« Reply #38 on: November 27, 2022, 10:35:18 pm »
I’m not even sure how to declare or use an advanced record.

Enable the modeswitch AdvancedRecords and then simply add methods to records like you do for class or object types.

Joanna

  • Hero Member
  • *****
  • Posts: 724
Re: IRC channel
« Reply #39 on: November 28, 2022, 12:18:26 am »
Quote
Enable the modeswitch AdvancedRecords and then simply add methods to records like you do for class or object types.

Is there a reason to use an advanced record instead of an object? What are the advantages over using object?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: IRC channel
« Reply #40 on: November 28, 2022, 02:13:25 am »
Is there a reason to use an advanced record instead of an object? What are the advantages over using object?
It's already discussed in detail a while ago. You can search the forum if you want to learn more.

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: IRC channel
« Reply #41 on: November 28, 2022, 02:28:47 am »
Is there a reason to use an advanced record instead of an object? What are the advantages over using object?
In a nutshell, an advanced record does _not_ have _any_ polymorphic calls. which means the compiler knows at compile time, which code will be executed when one of its "method"s is invoked.  IOW, there are no indirect or indexed calls to its functions/procedures/methods.

Of course, that advantage comes at the expense of some "disadvantages", for instance, an advanced record cannot inherit from anything nor can it be inherited by something else (which depending your viewpoint, may or may not be a good thing.)

Advanced records are the seed of OOP.  Add a virtual method table and you get objects (or classes), inheritance, polymorphism and another bunch of "goodies" (or not so "goodies" depending on your viewpoint.)

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Joanna

  • Hero Member
  • *****
  • Posts: 724
Re: IRC channel
« Reply #42 on: November 29, 2022, 02:21:28 am »
Quote
In a nutshell, an advanced record does _not_ have _any_ polymorphic calls. which means the compiler knows at compile time, which code will be executed when one of its "method"s is invoked.  IOW, there are no indirect or indexed calls to its functions/procedures/methods.

Thanks for clarifying. That would be useful for more simple things.
Do objects inherit advanced records? Besides not allowing virtual methods and inheritance, do the advanced records take less resources than a comparable object with same structure ?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: IRC channel
« Reply #43 on: November 29, 2022, 03:37:07 am »
Thanks for clarifying. That would be useful for more simple things.
You're welcome.  Advanced records are a good choice when 1. you don't need polymorphism, 2. you don't need them to inherit from something and 3. there is no need for something else (object or class) to inherit from them (since an advanced record cannot be inherited from.)  An advanced record is basically a normal record that in addition to listing fields also has a list of functions and procedures that have access (can use) the fields as well as a set of visibility specifiers and possibly a list of properties but, functionally, it pretty much is the same as a record that is restricted to be used by the list of functions, procedures, properties it declares in its body.   Other than the syntactic sugar advanced records provide (properties being the "sweetest" part), anything an advanced record can do can be done with a plain record.


Do objects inherit advanced records?
No but, _conceptually_ an "object" (not a class) can be thought of as the combination of an advanced record and a virtual method table (a VMT, whose existence is what enables inheritance and polymorphism.)

A class is very similar to an object in that it also has a VMT but, unlike an object, a class is always allocated on the heap whereas, both, an object or an advanced record can be allocated _either_ on the heap or, unlike classes, on the stack too.

The fact that a class is always allocated on the heap is what allows the compiler to hide that a class is a pointer (it dereferences the pointer automatically, therefore the programmer doesn't have to type "^" to access the class' fields.)

Besides not allowing virtual methods and inheritance, do the advanced records take less resources than a comparable object with same structure ?
Yes, because an advanced record does _not_ have a VMT, therefore it always uses less memory than an "equivalent" object or class.  That said, in most cases, the additional memory that is taken by the VMT isn't something that is worth losing any sleep over.

Objects were a bit of a problem when stacks were limited to 64K.  Initially, a class was pretty much an object that was always allocated on the heap (which did not have the 64K limit) and, because it was always allocated on the heap, the compiler could hide the fact that the class variable is a pointer by doing automatic dereferencing.  As time went by, classes gained features while objects were left behind (I believe Delphi has deprecated objects but, I could be wrong about that.)

Given that in today's machine, there really is no limit to how large a stack can be, memory is no longer an issue for the old objects.

HTH.
« Last Edit: November 29, 2022, 03:41:21 am by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: IRC channel
« Reply #44 on: November 29, 2022, 09:11:37 am »
Quote
In a nutshell, an advanced record does _not_ have _any_ polymorphic calls. which means the compiler knows at compile time, which code will be executed when one of its "method"s is invoked.  IOW, there are no indirect or indexed calls to its functions/procedures/methods.

Thanks for clarifying. That would be useful for more simple things.
Do objects inherit advanced records? Besides not allowing virtual methods and inheritance, do the advanced records take less resources than a comparable object with same structure ?

If an old style object does not have a constructor, nor any methods marked "virtual" then the same is true. (I need to check when/if/how the constructor influences this).


Yes, because an advanced record does _not_ have a VMT, therefore it always uses less memory than an "equivalent" object or class.  That said, in most cases, the additional memory that is taken by the VMT isn't something that is worth losing any sleep over.

Old style objects afaik only get a VMT, if they have virtual methods.


« Last Edit: November 29, 2022, 09:14:39 am by Martin_fr »

 

TinyPortal © 2005-2018