Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-16 Thread Ryan Joseph via fpc-devel


> On May 10, 2021, at 3:18 PM, Ryan Joseph  wrote:
> 
> Lets focus on the record approach for now then. I don't think I know enough 
> to understand where are the pitfalls are.

This was another thing I wanted off my mind since a couple years ago already so 
I got a pretty good start of an implementation. Since Sven has made it pretty 
clear we can't add ARC to Pascal without altering all instances of TObject, 
this is the next best thing. Together with record management operators this is 
how we can achieve "smart pointers" in Pascal.

I've constrained the implementation to hoisting the following members:

* Fields (duplicate field names with the record gives errors)
* Properties (last-wins, like in class hierarchies)
* Methods (and overloading with the method itself)
* for..in enumerator so container classes can be used naturally (other 
operators are not supported to keep the implementation simple for 99% use cases)
* Hoisting happens only by subscripting from the outside, so not within the 
record using implicit-self.
* Only records + classes are supported types (in the interest of keep the 
feature for ARC and not other things like nullable types or traits/mix-ins 
etc...)

https://bugs.freepascal.org/view.php?id=38872

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-11 Thread Sven Barth via fpc-devel

Am 10.05.2021 um 23:18 schrieb Ryan Joseph via fpc-devel:



On May 10, 2021, at 3:05 PM, Sven Barth via fpc-devel 
 wrote:

Why should they? You pass the reference to a non-reference counted 
parameter/field/variable, the reference count is increased and then what? It 
sits there for the remaining life time of the program, because nothing 
decrements the reference count?

I see what you mean. The FGL containers also call Finalize though when the 
container is freed so it does indeed keep balanced.
But only if the generic container is indeed specialized with the 
refcounted type. If it's e.g. TObject then the whole thing is up in the 
air again, because the whole point is that we *don't* want to burden 
non-reference counted class types with the reference counting stuff (and 
the need to check at runtime whether the type is reference counted or 
not *is* a burden).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-10 Thread Ryan Joseph via fpc-devel


> On May 10, 2021, at 3:05 PM, Sven Barth via fpc-devel 
>  wrote:
> 
> Why should they? You pass the reference to a non-reference counted 
> parameter/field/variable, the reference count is increased and then what? It 
> sits there for the remaining life time of the program, because nothing 
> decrements the reference count?

I see what you mean. The FGL containers also call Finalize though when the 
container is freed so it does indeed keep balanced.

Lets focus on the record approach for now then. I don't think I know enough to 
understand where are the pitfalls are.

> You should reread the visibility rules of Object Pascal:
> - private: identifier is visible inside the whole unit
> - strict private: identifier is only visible inside code of the class
> - protected: identifier is visible inside the whole unit as well as inside 
> descendants of the class as well as type helpers
> - strict protected: identifier is visible inside code of the class, inside 
> descendants of the class as well as type helpers
> - public: identifier is visible in the whole unit and (if it's declared in 
> the interface section) any unit that includes that unit
> - published: like public, but with RTTI data

yes, yes, I know. I thought we'd do something different.

> 
>> Some things:
>> 
>> 1) What do read/write access even mean in the context of the default 
>> properties? The terms don't really make much sense given what the the 
>> property does. Right now the property could be read only or write only but 
>> those don't really have any affect on the hoisting process itself so it's 
>> kind of deceptive. Methods are always "read-only" but i guess you could 
>> hoist fields/properties and inherit the access level of the default 
>> property. No idea if that's helpful or just adding needless complexity. Any 
>> ideas?
> Property accessors indeed don't really make sense. Maybe a "default field" 
> would be better than a "default property".

"Default field" is certainly more unique and thus better. We'll have to think 
about this more.

> 
>> 2) I also think there needs to be another name for the feature than "default 
>> property" since this term is already used for array indexers and could even 
>> be used for something like traits in the future (traits would be reusing 
>> much of this code). I need to add some enum names and default_property is 
>> already used so I need to think of something else.
>> 
>> 3) What about allowing type pointers as default properties? This should be 
>> possible and is in the spirit of the feature anyways, that is ref counting. 
>> We may need to add some additional logic to properties (just internally) so 
>> that they can be used with pointers but I'm not sure about that yet.
> Pointers are only useful if the ^ "operator" is hoisted as well.

I meant to say pointers to records so yes the ^. would need to be there. I 
haven't looked into how this would be implemented but I got it working with 
classes for now. It would be nice to make pointers to records be possible for 
smart pointers so I'll look into that later.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-10 Thread Sven Barth via fpc-devel

Am 09.05.2021 um 17:14 schrieb Ryan Joseph via fpc-devel:



On May 9, 2021, at 3:40 AM, Sven Barth  wrote:

=== code begin ===

{$mode objfpc}

type
   TTest = class
   protected
 procedure DoSomething;
   end;

   TTestSub = class refcounted(TTest)
   public
 procedure Test;
   end;

procedure TTest.DoSomething;
begin
   // maybe this functions stores the reference
   SomeFuncThatTakesAObject(Self);
end;

procedure TTest.Test;
begin
   DoSomething;
end;

=== code end ===

I see, the reference counting is broken because you move up into a non-ref 
counted class. Yeah that's something programers simply should not do or be 
prevented from doing. I don't see this particular case being a problem however 
because your ref counted object is going to be in the base of a hierarchy, 
probably enforced even. The only reason for opt-in ARC is so we don't pollute 
TObject but it still doesn't mean that  you should be adding this in the middle 
of class trees.


But that won't stop users from introducing reference counted classes 
somewhere down in the tree. Enabling reference counting by type is 
essentially introducing a new class hierarchy and that makes it useless 
for interacting with the existing RTL/FCL/LCL.



Here is the bigger problem:

var
   list: TObjectList;

procedure HandleObject(obj: TObject);
begin
// the list now stores the class but it's lost ref-counting because it was 
cast to TObject
list.Add(obj);
end;

var
   obj: TTestSub;
begin
   HandleObject(obj);
end;

or

var
   obj: TObject;
begin
   // we  lost ref counting now!
   obj := TTestSub.Create;
   HandleObject(obj);
end;

Once you cast away from your managed class type things fall apart. Records aid 
this by not allowing casting but you could enforce some kinds of checks for 
managed classes if you wanted to. Doesn't seem like a deal breaker to me if you 
add new type rules for passing/assigning.


That is exactly *the same* problem, not a "bigger" one. It doesn't 
matter if the instance is passed to a function right away or through 
using Self in a parent class, the result is the same: the reference 
count is no longer accurate.


And *that* is why I'm in favor of an approach that is external to the 
class. It's much clearer then that this is not something inherent to the 
class and thus users won't expect this to be handled transparently (and 
this is also why I'm against a keyword like Michael suggested, it only 
wakes expectations that we won't and can't fullfill).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-10 Thread Sven Barth via fpc-devel

Am 09.05.2021 um 16:58 schrieb Ryan Joseph via fpc-devel:



On May 9, 2021, at 3:40 AM, Sven Barth  wrote:

It seems that you don't work much with classes then. If one disallows the 
assignment of a reference counted class to a non-reference counted one then you 
can't use e.g. TStringList.Objects. There is also the problem of method 
pointers, which essentially only have a Pointer as Self data. Also a reference 
might escape in a parent class (for this example I'll use the syntax I used in 
my branch):

I use classes all the time but I thought that any assignments or passing to 
function args call the management operators. So if you pass a managed class to 
a TStringList.Add for example then AddRef will indeed by called. You're saying 
this isn't the case? I know the FGL classes can work with ref counted objects 
so why is it any different if a class type was managed and then passed into one 
of these types?


Why should they? You pass the reference to a non-reference counted 
parameter/field/variable, the reference count is increased and then 
what? It sits there for the remaining life time of the program, because 
nothing decrements the reference count?



Anyways I wrote up a little wiki with some potential implementation notes about a default 
property (which overlaps on the "defaults implements" as traits stuff). Important 
points are restricting what types can be default properties (classes and maybe/probably 
typed pointers) and limiting hoisting to subscripting, so it's kind of like the -> 
operator overload in C++.

https://github.com/genericptr/freepascal/wiki/Default-property

It shouldn't hoist only public members, it should hoist according to the 
visibility rules (thus the hoisting depends on the callsite), otherwise it 
won't behave like Pascal classes do and thus we can forget it right away.

So this means if the property is in the private section it looks at private 
visibility in the parent class? Yeah that's probably right we need to do that.


You should reread the visibility rules of Object Pascal:
- private: identifier is visible inside the whole unit
- strict private: identifier is only visible inside code of the class
- protected: identifier is visible inside the whole unit as well as 
inside descendants of the class as well as type helpers
- strict protected: identifier is visible inside code of the class, 
inside descendants of the class as well as type helpers
- public: identifier is visible in the whole unit and (if it's declared 
in the interface section) any unit that includes that unit

- published: like public, but with RTTI data


Some things:

1) What do read/write access even mean in the context of the default properties? The 
terms don't really make much sense given what the the property does. Right now the 
property could be read only or write only but those don't really have any affect on the 
hoisting process itself so it's kind of deceptive. Methods are always 
"read-only" but i guess you could hoist fields/properties and inherit the 
access level of the default property. No idea if that's helpful or just adding needless 
complexity. Any ideas?
Property accessors indeed don't really make sense. Maybe a "default 
field" would be better than a "default property".



2) I also think there needs to be another name for the feature than "default 
property" since this term is already used for array indexers and could even be used 
for something like traits in the future (traits would be reusing much of this code). I 
need to add some enum names and default_property is already used so I need to think of 
something else.

3) What about allowing type pointers as default properties? This should be 
possible and is in the spirit of the feature anyways, that is ref counting. We 
may need to add some additional logic to properties (just internally) so that 
they can be used with pointers but I'm not sure about that yet.

Pointers are only useful if the ^ "operator" is hoisted as well.

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-10 Thread Ryan Joseph via fpc-devel
Over the weekend I fixed up my old default property code to work with records 
only which implement classes (which reduced lots of the complexity). It's 
actually a pretty clean and small implementation so I put a patch you can look 
at and try. It's not decided upon but this is a place to start should we decide 
to go this route for "start pointers".

https://bugs.freepascal.org/view.php?id=38872

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-09 Thread Ryan Joseph via fpc-devel


> On May 9, 2021, at 3:40 AM, Sven Barth  wrote:
> 
> === code begin ===
> 
> {$mode objfpc}
> 
> type
>   TTest = class
>   protected
> procedure DoSomething;
>   end;
> 
>   TTestSub = class refcounted(TTest)
>   public
> procedure Test;
>   end;
> 
> procedure TTest.DoSomething;
> begin
>   // maybe this functions stores the reference
>   SomeFuncThatTakesAObject(Self);
> end;
> 
> procedure TTest.Test;
> begin
>   DoSomething;
> end;
> 
> === code end ===

I see, the reference counting is broken because you move up into a non-ref 
counted class. Yeah that's something programers simply should not do or be 
prevented from doing. I don't see this particular case being a problem however 
because your ref counted object is going to be in the base of a hierarchy, 
probably enforced even. The only reason for opt-in ARC is so we don't pollute 
TObject but it still doesn't mean that  you should be adding this in the middle 
of class trees.

Here is the bigger problem:

var
  list: TObjectList;

procedure HandleObject(obj: TObject);
begin
   // the list now stores the class but it's lost ref-counting because it was 
cast to TObject
   list.Add(obj);
end;

var
  obj: TTestSub;
begin
  HandleObject(obj);
end;

or

var
  obj: TObject;
begin
  // we  lost ref counting now!
  obj := TTestSub.Create;
  HandleObject(obj);
end;

Once you cast away from your managed class type things fall apart. Records aid 
this by not allowing casting but you could enforce some kinds of checks for 
managed classes if you wanted to. Doesn't seem like a deal breaker to me if you 
add new type rules for passing/assigning.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-09 Thread Ryan Joseph via fpc-devel


> On May 9, 2021, at 3:40 AM, Sven Barth  wrote:
> 
> It seems that you don't work much with classes then. If one disallows the 
> assignment of a reference counted class to a non-reference counted one then 
> you can't use e.g. TStringList.Objects. There is also the problem of method 
> pointers, which essentially only have a Pointer as Self data. Also a 
> reference might escape in a parent class (for this example I'll use the 
> syntax I used in my branch):

I use classes all the time but I thought that any assignments or passing to 
function args call the management operators. So if you pass a managed class to 
a TStringList.Add for example then AddRef will indeed by called. You're saying 
this isn't the case? I know the FGL classes can work with ref counted objects 
so why is it any different if a class type was managed and then passed into one 
of these types?

>> Anyways I wrote up a little wiki with some potential implementation notes 
>> about a default property (which overlaps on the "defaults implements" as 
>> traits stuff). Important points are restricting what types can be default 
>> properties (classes and maybe/probably typed pointers) and limiting hoisting 
>> to subscripting, so it's kind of like the -> operator overload in C++.
>> 
>> https://github.com/genericptr/freepascal/wiki/Default-property
> It shouldn't hoist only public members, it should hoist according to the 
> visibility rules (thus the hoisting depends on the callsite), otherwise it 
> won't behave like Pascal classes do and thus we can forget it right away.

So this means if the property is in the private section it looks at private 
visibility in the parent class? Yeah that's probably right we need to do that.

Some things:

1) What do read/write access even mean in the context of the default 
properties? The terms don't really make much sense given what the the property 
does. Right now the property could be read only or write only but those don't 
really have any affect on the hoisting process itself so it's kind of 
deceptive. Methods are always "read-only" but i guess you could hoist 
fields/properties and inherit the access level of the default property. No idea 
if that's helpful or just adding needless complexity. Any ideas?

2) I also think there needs to be another name for the feature than "default 
property" since this term is already used for array indexers and could even be 
used for something like traits in the future (traits would be reusing much of 
this code). I need to add some enum names and default_property is already used 
so I need to think of something else. 

3) What about allowing type pointers as default properties? This should be 
possible and is in the spirit of the feature anyways, that is ref counting. We 
may need to add some additional logic to properties (just internally) so that 
they can be used with pointers but I'm not sure about that yet. 

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-09 Thread Sven Barth via fpc-devel

Am 08.05.2021 um 19:38 schrieb Ryan Joseph via fpc-devel:



On May 8, 2021, at 11:18 AM, Sven Barth  wrote:

It's not about reference counted classes vs. managed records, but about whether 
it's *per type* or *per variable*, the implementation details are completely 
irrelevant for now.

So the biggest concern you see if that classes are easier to assign to 
non-reference counted classes? The only difference between classes and records 
in this regard is that records give errors unless you assign directly to the 
same record type, where classes can be assigned to super-classes which may not 
be managed.

As you say there would need to be at least a warning if you cast a managed 
class to another class type or make it forbidden completely. I don't see that 
as a deal breaker personally but you seem to feel pretty strongly about it.


It seems that you don't work much with classes then. If one disallows 
the assignment of a reference counted class to a non-reference counted 
one then you can't use e.g. TStringList.Objects. There is also the 
problem of method pointers, which essentially only have a Pointer as 
Self data. Also a reference might escape in a parent class (for this 
example I'll use the syntax I used in my branch):


=== code begin ===

{$mode objfpc}

type
  TTest = class
  protected
    procedure DoSomething;
  end;

  TTestSub = class refcounted(TTest)
  public
    procedure Test;
  end;

procedure TTest.DoSomething;
begin
  // maybe this functions stores the reference
  SomeFuncThatTakesAObject(Self);
end;

procedure TTest.Test;
begin
  DoSomething;
end;

=== code end ===

Obviously these problems won't be solved with the alternative approach 
either, but likely one can make clear more easily that the use case is 
for local instances.



Anyways I wrote up a little wiki with some potential implementation notes about a default 
property (which overlaps on the "defaults implements" as traits stuff). Important 
points are restricting what types can be default properties (classes and maybe/probably 
typed pointers) and limiting hoisting to subscripting, so it's kind of like the -> 
operator overload in C++.

https://github.com/genericptr/freepascal/wiki/Default-property
It shouldn't hoist only public members, it should hoist according to the 
visibility rules (thus the hoisting depends on the callsite), otherwise 
it won't behave like Pascal classes do and thus we can forget it right away.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-08 Thread Ryan Joseph via fpc-devel


> On May 8, 2021, at 11:18 AM, Sven Barth  wrote:
> 
> It's not about reference counted classes vs. managed records, but about 
> whether it's *per type* or *per variable*, the implementation details are 
> completely irrelevant for now.

So the biggest concern you see if that classes are easier to assign to 
non-reference counted classes? The only difference between classes and records 
in this regard is that records give errors unless you assign directly to the 
same record type, where classes can be assigned to super-classes which may not 
be managed.

As you say there would need to be at least a warning if you cast a managed 
class to another class type or make it forbidden completely. I don't see that 
as a deal breaker personally but you seem to feel pretty strongly about it.

Anyways I wrote up a little wiki with some potential implementation notes about 
a default property (which overlaps on the "defaults implements" as traits 
stuff). Important points are restricting what types can be default properties 
(classes and maybe/probably typed pointers) and limiting hoisting to 
subscripting, so it's kind of like the -> operator overload in C++.

https://github.com/genericptr/freepascal/wiki/Default-property

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-08 Thread Sven Barth via fpc-devel

Am 08.05.2021 um 18:23 schrieb Ryan Joseph via fpc-devel:



On May 8, 2021, at 7:59 AM, Sven Barth via fpc-devel 
 wrote:

It has the exact same problems that my branch had (especially the interaction 
of reference counted instances with non-reference counted ones).

Using a variable/parameter/field based approach (like the idea with managed 
records and default fields) is the more flexible one compared to the type or 
instance based one and thus it's more favorable.

I still don't understand how the record approach is that much different from a managed 
class type which calls the same set of management operators.  Can we make a pros-cons 
list to clear this up and give an example of "especially the interaction of 
reference counted instances with non-reference counted ones"?

Here's the most recent things we brought up:

- Records can't be cast in a way that would break reference counting (like a 
managed class being cast to TObject would).
- Generic records would create a proliferation of new types for all classes you wanted managed, so instead of using 
TFPGList you're using TManagedSomeObjectList or TManaged>, or 
worse yet "specialize TManaged>"

Otherwise the same set of circular references exists but I'm not sure about 
your concern about mixing managed types yet.
It's not about reference counted classes vs. managed records, but about 
whether it's *per type* or *per variable*, the implementation details 
are completely irrelevant for now.


And the problems are assigning a reference counted class instance to a 
non-reference counted variable or parameter. Also casting such a 
reference counted class to a non-reference counted one (e.g. to 
TObject). Allowing these kind of operations would either need to be 
forbidden which would restrict the usability of such classes or they 
could potentially lead to memory leaks or premature freeing. Not to 
mention how calling the destructor would react if the reference count 
isn't 0.


By using a mechanism based on the variable/field/parameter type you have 
a much more fine grained control and if one leaves out the implicit 
assignment from the wrapped class type to the non-wrapped one then one 
needs to do an explicit conversion.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-08 Thread Ryan Joseph via fpc-devel


> On May 8, 2021, at 7:59 AM, Sven Barth via fpc-devel 
>  wrote:
> 
> It has the exact same problems that my branch had (especially the interaction 
> of reference counted instances with non-reference counted ones).
> 
> Using a variable/parameter/field based approach (like the idea with managed 
> records and default fields) is the more flexible one compared to the type or 
> instance based one and thus it's more favorable.

I still don't understand how the record approach is that much different from a 
managed class type which calls the same set of management operators.  Can we 
make a pros-cons list to clear this up and give an example of "especially the 
interaction of reference counted instances with non-reference counted ones"?

Here's the most recent things we brought up:

- Records can't be cast in a way that would break reference counting (like a 
managed class being cast to TObject would).
- Generic records would create a proliferation of new types for all classes you 
wanted managed, so instead of using TFPGList you're using 
TManagedSomeObjectList or TManaged>, or worse yet 
"specialize TManaged>"

Otherwise the same set of circular references exists but I'm not sure about 
your concern about mixing managed types yet.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-08 Thread Sven Barth via fpc-devel

Am 07.05.2021 um 23:16 schrieb Ryan Joseph via fpc-devel:



On May 7, 2021, at 2:52 PM, Sven Barth  wrote:

As said the main problem of reference counting on object instances, especially 
if enabled by default like the Delphi NextGen compiler did, will lead to 
problems in *existing* code and thus is a no-go.


What did you think about me other email that had ideas to add compiler directives like 
$M+? The way record management operators are implemented is that if you include any of 
the operators then the type becomes "managed" in the same way other ref counted 
types are handled.

For classes this is different because there is a hierarchy which is now altered 
but the compiler could still insert a hidden super class above it and use that 
to store the extra data. Indeed this would mean that existing classes (like the 
RTL) would not be eligible for reference counting unless it was compiled using 
said directive.

For example the follow class:

{$RETAINED+}
type
  TMyObject = class(TBaseClass)
  end;
{$RETAINED-}

would become:

type
  TMyObject_RefCounted = class abstract(TBaseClass)
   strict private
 refCount: LongInt;
  end;
  TMyObject = class(TMyObject_RefCounted)
  end;

and now "TMyObject" is a managed type and Initialize/Finalize/AddRef/Copy will 
be called. It occurs to me now though that the ref counting would be tied to the type so 
if you cast the class to TObject and passed it around then ref counting wouldn't happen. 
Not sure if that's a deal breaker or not but it could easily cause hard to fix memory 
leaks just like normal classes. :)


It has the exact same problems that my branch had (especially the 
interaction of reference counted instances with non-reference counted ones).


Using a variable/parameter/field based approach (like the idea with 
managed records and default fields) is the more flexible one compared to 
the type or instance based one and thus it's more favorable.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-07 Thread Ryan Joseph via fpc-devel


> On May 7, 2021, at 2:52 PM, Sven Barth  wrote:
> 
> As said the main problem of reference counting on object instances, 
> especially if enabled by default like the Delphi NextGen compiler did, will 
> lead to problems in *existing* code and thus is a no-go. 
> 

What did you think about me other email that had ideas to add compiler 
directives like $M+? The way record management operators are implemented is 
that if you include any of the operators then the type becomes "managed" in the 
same way other ref counted types are handled.

For classes this is different because there is a hierarchy which is now altered 
but the compiler could still insert a hidden super class above it and use that 
to store the extra data. Indeed this would mean that existing classes (like the 
RTL) would not be eligible for reference counting unless it was compiled using 
said directive.

For example the follow class:

{$RETAINED+}
type
 TMyObject = class(TBaseClass)
 end;
{$RETAINED-}

would become:

type
 TMyObject_RefCounted = class abstract(TBaseClass)
  strict private
refCount: LongInt;
 end;
 TMyObject = class(TMyObject_RefCounted)
 end;

and now "TMyObject" is a managed type and Initialize/Finalize/AddRef/Copy will 
be called. It occurs to me now though that the ref counting would be tied to 
the type so if you cast the class to TObject and passed it around then ref 
counting wouldn't happen. Not sure if that's a deal breaker or not but it could 
easily cause hard to fix memory leaks just like normal classes. :)

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-07 Thread Sven Barth via fpc-devel
Ryan Joseph via fpc-devel  schrieb am Fr.,
7. Mai 2021, 05:58:

>
>
> > On May 6, 2021, at 7:14 PM, Ryan Joseph  wrote:
> >
> > This can be detected at compile and at least give a warning. "a" is a
> member of TR and the element type of "a" is TR, then we're assigning TR to
> said array. It's that simple I think.
>
> It also occurs to me that record management operators already allow these
> types of circular references. It's just par for the course with ref
> counting and something programmers need to be aware of.
>

As said the main problem of reference counting on object instances,
especially if enabled by default like the Delphi NextGen compiler did, will
lead to problems in *existing* code and thus is a no-go.

Regards,
Sven

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-06 Thread Ryan Joseph via fpc-devel


> On May 6, 2021, at 7:14 PM, Ryan Joseph  wrote:
> 
> This can be detected at compile and at least give a warning. "a" is a member 
> of TR and the element type of "a" is TR, then we're assigning TR to said 
> array. It's that simple I think.

It also occurs to me that record management operators already allow these types 
of circular references. It's just par for the course with ref counting and 
something programmers need to be aware of.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-06 Thread Ryan Joseph via fpc-devel


> On May 6, 2021, at 5:41 PM, Martin Frb via fpc-devel 
>  wrote:
> 
> You can already cause ref circles, no classes needed.
> 
> type
>   TR = record
> a: array of TR;
>   end;
> 
> var
>   x: TR;
> begin
>   SetLength(x.a,99);
>   x.a[0] := x;
> end.

This can be detected at compile and at least give a warning. "a" is a member of 
TR and the element type of "a" is TR, then we're assigning TR to said array. 
It's that simple I think.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] (ref types / circles) Re: Defer keyword

2021-05-06 Thread Nikolai Zhubr via fpc-devel

Hi Martin,

07.05.2021 2:41, Martin Frb via fpc-devel:

On 07/05/2021 01:36, Nikolai Zhubr via fpc-devel wrote:


Indeed. However, unfortunately classes are substantially different in
that they can cause reference circles,

You can already cause ref circles, no classes needed.


Yes, records and objects are the same as classes in this respect. You 
cannot do circles with any other types, AFAIK.



Regards,
Nikolai


type
   TR = record
 a: array of TR;
   end;

var
   x: TR;
begin
   SetLength(x.a,99);
   x.a[0] := x;
end.


___
fpc-devel maillist - fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel