why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Dennis
I was trying to use a generic class TDictionary<T>  with type T. This
class has a method that compares a variable of T with another one.

When I specialize a class using this TDictionary with a type:

TSecurity = object
   ....
end;


e.g. TNewDict = class(TDictionary<String, TSecurity>);

it raise a compiler complaining that my TSecurity type has no operator =
defined.

But when I try to add like this:

TSecurity = object
   ....
class operator =  (constref aLeft, aRight: TSecurity ): Boolean;
//<---compiler Error: Procedure or Function expected

end;


However, the following is OK
{$MODESWITCH advancedrecords}
TSecurity = record
   ....
class operator =  (constref aLeft, aRight: TSecurity ): Boolean; //<---OK

end;


Why class operator is accepted for advanced records but not old fashion
object???

I cannot use advance record because it does have inherit methods. I need
method inheritance for my object.

Dennis
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Michael Van Canneyt


On Wed, 15 Aug 2018, Dennis wrote:

> I was trying to use a generic class TDictionary<T>  with type T. This
> class has a method that compares a variable of T with another one.
>
> When I specialize a class using this TDictionary with a type:
>
> TSecurity = object
>   ....
> end;
>
>
> e.g. TNewDict = class(TDictionary<String, TSecurity>);
>
> it raise a compiler complaining that my TSecurity type has no operator =
> defined.
>
> But when I try to add like this:
>
> TSecurity = object
>   ....
> class operator =  (constref aLeft, aRight: TSecurity ): Boolean;
> //<---compiler Error: Procedure or Function expected
>
> end;
Did you try creating an "old-fashioned" = operator ?

Something like

Operator = (l,r : TSecurity) z : boolean;

begin
   // compare here
end;

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Dennis


Michael Van Canneyt wrote:

>
>
> On Wed, 15 Aug 2018, Dennis wrote:
>
>> I was trying to use a generic class TDictionary<T>  with type T. This
>> class has a method that compares a variable of T with another one.
>>
>> When I specialize a class using this TDictionary with a type:
>>
>> TSecurity = object
>>   ....
>> end;
>>
>>
>> e.g. TNewDict = class(TDictionary<String, TSecurity>);
>>
>> it raise a compiler complaining that my TSecurity type has no
>> operator = defined.
>>
>> But when I try to add like this:
>>
>> TSecurity = object
>>   ....
>> class operator =  (constref aLeft, aRight: TSecurity ): Boolean;
>> //<---compiler Error: Procedure or Function expected
>>
>> end;
>
> Did you try creating an "old-fashioned" = operator ?
>
> Something like
>
> Operator = (l,r : TSecurity) z : boolean;
>
> begin
>   // compare here
> end;
>

Just tried.
It complained:   Fatal: Syntax error, "IMPLEMENTATION" expected but
"identifier OPERATOR" found

Dennis

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Michael Van Canneyt


On Wed, 15 Aug 2018, Dennis wrote:

>
>
> Michael Van Canneyt wrote:
>>
>>
>> On Wed, 15 Aug 2018, Dennis wrote:
>>
>>> I was trying to use a generic class TDictionary<T>  with type T. This
>>> class has a method that compares a variable of T with another one.
>>>
>>> When I specialize a class using this TDictionary with a type:
>>>
>>> TSecurity = object
>>>   ....
>>> end;
>>>
>>>
>>> e.g. TNewDict = class(TDictionary<String, TSecurity>);
>>>
>>> it raise a compiler complaining that my TSecurity type has no
>>> operator = defined.
>>>
>>> But when I try to add like this:
>>>
>>> TSecurity = object
>>>   ....
>>> class operator =  (constref aLeft, aRight: TSecurity ): Boolean;
>>> //<---compiler Error: Procedure or Function expected
>>>
>>> end;
>>
>> Did you try creating an "old-fashioned" = operator ?
>>
>> Something like
>>
>> Operator = (l,r : TSecurity) z : boolean;
>>
>> begin
>>   // compare here
>> end;
>>
>
> Just tried.
> It complained:   Fatal: Syntax error, "IMPLEMENTATION" expected but
> "identifier OPERATOR" found
Following works here:

Prograp testo;

Type
   TSecurity = Object
     a,b : Integer;
   end;

Operator = (l,r : TSecurity) z : boolean;

begin
   Z:=(l.a=r.a) and (L.b=r.b);
end;

begin
end.

But maybe you are using mode delphi ? If so, try separating out the object
definition in a separate unit which is not compiled in delphi mode.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
Am 15.08.2018 um 11:17 schrieb Michael Van Canneyt:

>
>
> On Wed, 15 Aug 2018, Dennis wrote:
>
>>
>>
>> Michael Van Canneyt wrote:
>>>
>>>
>>> On Wed, 15 Aug 2018, Dennis wrote:
>>>
>>>> I was trying to use a generic class TDictionary<T>  with type T.
>>>> This class has a method that compares a variable of T with another
>>>> one.
>>>>
>>>> When I specialize a class using this TDictionary with a type:
>>>>
>>>> TSecurity = object
>>>>   ....
>>>> end;
>>>>
>>>>
>>>> e.g. TNewDict = class(TDictionary<String, TSecurity>);
>>>>
>>>> it raise a compiler complaining that my TSecurity type has no
>>>> operator = defined.
>>>>
>>>> But when I try to add like this:
>>>>
>>>> TSecurity = object
>>>>   ....
>>>> class operator =  (constref aLeft, aRight: TSecurity ): Boolean;
>>>> //<---compiler Error: Procedure or Function expected
>>>>
>>>> end;
>>>
>>> Did you try creating an "old-fashioned" = operator ?
>>>
>>> Something like
>>>
>>> Operator = (l,r : TSecurity) z : boolean;
>>>
>>> begin
>>>   // compare here
>>> end;
>>>
>>
>> Just tried.
>> It complained:   Fatal: Syntax error, "IMPLEMENTATION" expected but
>> "identifier OPERATOR" found
>
> Following works here:
>
> Prograp testo;
>
> Type
>   TSecurity = Object
>     a,b : Integer;
>   end;
>
> Operator = (l,r : TSecurity) z : boolean;
>
> begin
>   Z:=(l.a=r.a) and (L.b=r.b);
> end;
>
> begin
> end.
>
> But maybe you are using mode delphi ? If so, try separating out the
> object
> definition in a separate unit which is not compiled in delphi mode.
A global operator won't help at all as (currently) the operator won't be
visible during the specialization. Only if the operator is visible
during the *generic's* declaration it would be picked up.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
In reply to this post by Dennis
Am 15.08.2018 um 10:59 schrieb Dennis:
> Why class operator is accepted for advanced records but not old
> fashion object???
Because objects are not records. Internally they are handled more
closely to classes than records.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Michael Van Canneyt
In reply to this post by Free Pascal - General mailing list


On Wed, 15 Aug 2018, Sven Barth via fpc-pascal wrote:

>>
>> But maybe you are using mode delphi ? If so, try separating out the
>> object
>> definition in a separate unit which is not compiled in delphi mode.
> A global operator won't help at all as (currently) the operator won't be
> visible during the specialization. Only if the operator is visible
> during the *generic's* declaration it would be picked up.

That is contrary to the class operator, which is also only visible during
specialization, after all.

Is there a reason for this behaviour ?

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
Am 15.08.2018 um 17:29 schrieb Michael Van Canneyt:

>
>
> On Wed, 15 Aug 2018, Sven Barth via fpc-pascal wrote:
>
>>>
>>> But maybe you are using mode delphi ? If so, try separating out the
>>> object
>>> definition in a separate unit which is not compiled in delphi mode.
>> A global operator won't help at all as (currently) the operator won't
>> be visible during the specialization. Only if the operator is visible
>> during the *generic's* declaration it would be picked up.
>
> That is contrary to the class operator, which is also only visible during
> specialization, after all.
>
> Is there a reason for this behaviour ?
The operator of a record is visible together with the record, however a
global operator is not. When specializing the unit scope of the
declaration of the *generic* is restored thus no helpers or global
operators of the current scope are visible except they are part of the
type parameter.
I do want to try to change this in the future, but I need to be careful
to not open a different can of worms (as Delphi doesn't do it this way).

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Dennis Poon
In reply to this post by Free Pascal - General mailing list


Sven Barth via fpc-pascal wrote:
> Am 15.08.2018 um 10:59 schrieb Dennis:
>> Why class operator is accepted for advanced records but not old
>> fashion object???
> Because objects are not records. Internally they are handled more
> closely to classes than records.
>
Would it be too hard to also implement class operators for old fashion
objects?  That will be very  nice.

Dennis

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Michael Van Canneyt
In reply to this post by Free Pascal - General mailing list
> Am 15.08.2018 um 17:29 schrieb Michael Van Canneyt:
>>
>>
>> On Wed, 15 Aug 2018, Sven Barth via fpc-pascal wrote:
>>
>>>>
>>>> But maybe you are using mode delphi ? If so, try separating out the
>>>> object
>>>> definition in a separate unit which is not compiled in delphi mode.
>>> A global operator won't help at all as (currently) the operator won't
>>> be visible during the specialization. Only if the operator is visible
>>> during the *generic's* declaration it would be picked up.
>>
>> That is contrary to the class operator, which is also only visible
>> during
>> specialization, after all.
>>
>> Is there a reason for this behaviour ?
> The operator of a record is visible together with the record, however a
> global operator is not. When specializing the unit scope of the
> declaration of the *generic* is restored thus no helpers or global
> operators of the current scope are visible except they are part of the
> type parameter.
> I do want to try to change this in the future, but I need to be careful
> to not open a different can of worms (as Delphi doesn't do it this way).

Purely reasoning in terms of data structures:

I would think you 'attach' operators to the type for which they are defined ?
If the 'attach' link structure contains the unit in which the operator
definition resides, you can check whether this unit is visible, and if
yes, the operator is 'usable'.

Michael.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
Am 16.08.2018 um 12:47 schrieb Michael Van Canneyt:

>> Am 15.08.2018 um 17:29 schrieb Michael Van Canneyt:
>>>
>>> On Wed, 15 Aug 2018, Sven Barth via fpc-pascal wrote:
>>>
>>>>> But maybe you are using mode delphi ? If so, try separating out the
>>>>> object
>>>>> definition in a separate unit which is not compiled in delphi mode.
>>>> A global operator won't help at all as (currently) the operator won't
>>>> be visible during the specialization. Only if the operator is visible
>>>> during the *generic's* declaration it would be picked up.
>>> That is contrary to the class operator, which is also only visible
>>> during
>>> specialization, after all.
>>>
>>> Is there a reason for this behaviour ?
>> The operator of a record is visible together with the record, however a
>> global operator is not. When specializing the unit scope of the
>> declaration of the *generic* is restored thus no helpers or global
>> operators of the current scope are visible except they are part of the
>> type parameter.
>> I do want to try to change this in the future, but I need to be careful
>> to not open a different can of worms (as Delphi doesn't do it this way).
> Purely reasoning in terms of data structures:
>
> I would think you 'attach' operators to the type for which they are defined ?
> If the 'attach' link structure contains the unit in which the operator
> definition resides, you can check whether this unit is visible, and if
> yes, the operator is 'usable'.
No, they are not attached. Remember that global operators don't need to
reside in the same unit as the type they're operating on. And it would
be rather useless time to search for existing operator overloads for any
type when the program uses none of them in the end. Thus the compiler
looks for operators on the fly once it encounters the use of one, it's
just like looking for method calls with a slightly different syntax. The
scope of a structured type is always looked in first and then all units
in the scope are searched for global operators.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
In reply to this post by Dennis Poon
Am 16.08.2018 um 12:23 schrieb Dennis Poon:

>
>
> Sven Barth via fpc-pascal wrote:
>> Am 15.08.2018 um 10:59 schrieb Dennis:
>>> Why class operator is accepted for advanced records but not old
>>> fashion object???
>> Because objects are not records. Internally they are handled more
>> closely to classes than records.
>>
> Would it be too hard to also implement class operators for old fashion
> objects?  That will be very  nice.
It shouldn't be hard. Feel free to provide a patch together with some
tests and it will be taken under consideration.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Ryan Joseph


> On Aug 16, 2018, at 8:55 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> It shouldn't be hard. Feel free to provide a patch together with some tests and it will be taken under consideration.

So the reason that objects/classes in FPC don’t have operators in the class (like advanced records) is for Delphi compatibility? That would be great if operators were unified across records/classes.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Maciej Izak
2018-08-17 17:48 GMT+02:00 Ryan Joseph <[hidden email]>:
So the reason that objects/classes in FPC don’t have operators in the class (like advanced records) is for Delphi compatibility? That would be great if operators were unified across records/classes.

In Delphi (NEXTGEN for mobile platforms and Linux) is possible to use class operators for classes (in NEXTGEN classes are managed by ARC).

More info:


the existence of class operators for classes in NEXTGEN is presented as "a side effect of the new Automatic Reference Counting support"

--
Best regards,
Maciej Izak

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Ryan Joseph <[hidden email]> schrieb am Fr., 17. Aug. 2018, 18:22:


> On Aug 16, 2018, at 8:55 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> It shouldn't be hard. Feel free to provide a patch together with some tests and it will be taken under consideration.

So the reason that objects/classes in FPC don’t have operators in the class (like advanced records) is for Delphi compatibility? That would be great if operators were unified across records/classes.

Not entirely. In Delphi objects are deprecated, so as long as old code keeps compiling and running we can mess with them. 

However for classes there is the problem of temporary variables. Take a := b + c + d. That is essentially compiled as t := b + c; a := t + d. The compiler does not know whether the operator creates an instance or not (yes, there are circumstances when it can know that, but for the general case it can't) and thus this would potentially lead to memory leaks. 

Thus automatic reference counting or garbage collection or something like that is required for this to work nicely. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Bo Berglund
On Sat, 18 Aug 2018 03:19:55 +0200, Sven Barth via fpc-pascal
<[hidden email]> wrote:

>In Delphi objects are deprecated

Huh?
ObjectPascal deprecating objects?
Sounds far-fetched.


--
Bo Berglund
Developer in Sweden

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Michael Van Canneyt


On Sat, 18 Aug 2018, Bo Berglund wrote:

> On Sat, 18 Aug 2018 03:19:55 +0200, Sven Barth via fpc-pascal
> <[hidden email]> wrote:
>
>> In Delphi objects are deprecated
>
> Huh?
> ObjectPascal deprecating objects?
> Sounds far-fetched.

Old-style TP Objects are deprecated, but classes are not.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Ryan Joseph
In reply to this post by Free Pascal - General mailing list


> On Aug 17, 2018, at 7:19 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> However for classes there is the problem of temporary variables. Take a := b + c + d. That is essentially compiled as t := b + c; a := t + d. The compiler does not know whether the operator creates an instance or not (yes, there are circumstances when it can know that, but for the general case it can't) and thus this would potentially lead to memory leaks.
>

I’m must be confused because classes already have operator overloads, they’re just in global scope outside of the class itself. Don’t all the same rules apply if the syntax is put inside the class (like in records) just the scope rules change?

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why can't we define class operator for old fashion object type, but ok for 'advanced record' type?

Free Pascal - General mailing list
Ryan Joseph <[hidden email]> schrieb am Sa., 18. Aug. 2018, 19:38:


> On Aug 17, 2018, at 7:19 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> However for classes there is the problem of temporary variables. Take a := b + c + d. That is essentially compiled as t := b + c; a := t + d. The compiler does not know whether the operator creates an instance or not (yes, there are circumstances when it can know that, but for the general case it can't) and thus this would potentially lead to memory leaks.
>

I’m must be confused because classes already have operator overloads, they’re just in global scope outside of the class itself. Don’t all the same rules apply if the syntax is put inside the class (like in records) just the scope rules change?

Delphi does not have global operator overloads and in FPC the problem I mentioned indeed happens with global overloads. It's just that not many people use global overloads for classes (especially now that generics are used more). 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal