Re: [fpc-pascal] Subclassing generic records?

2017-07-21 Thread Martin Schreiber
On Friday 21 July 2017 23:04:20 Ryan Joseph wrote:
> Thanks Sven, that’s one way around it.
>
> So is it by design that records don’t have inheritance or is this planned?
>
MSElang has a concept of unified record, object and class constructs. There a 
record is a simplified object which never has a VMT and has no methods. An 
object has a VMT only if the attribute [virtual] is given. An object can be 
instantiated in global or stack memory or on heap if it has a constructor() 
and destructor().
A class is an object which always is instantiated on heap and which provides 
implicit dereferencing. Classes can inherit from objects.
https://gitlab.com/mseide-msegui/mselang/wikis/home/mselang_objects
https://gitlab.com/mseide-msegui/mselang/wikis/home
(under construction).

Martin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Subclassing generic records?

2017-07-21 Thread Sven Barth via fpc-pascal
Am 21.07.2017 23:36 schrieb "Ryan Joseph" :
>
> Thanks Sven, that’s one way around it.
>
> So is it by design that records don’t have inheritance or is this planned?

Yes, that's by design and there are no plans to change this.

> and is it also by design that classes don’t allow operator overloads
inside them? That seems like an omission since the way they’re implemented
in records is much nicer imo.

There are two points you need to be aware of to understand why thinks are
the way they are:
First of global operator overloads were the first that were implemented in
FPC. Then Delphi came along and added record operator overloads, because
they needed them for generics. FPC followed, cause the global overloads are
useless in that case.
Secondly even for global operator overloads classes are not really that
suitable, cause in complex expressions (let's say "a * (b + c)") you'll
have the generation of temporary variables (in the example the result of "b
+ c"), but the compiler can't know whether it's really a temporary value
that it can free after the whole expression is handled or whether merely
the instance that had been passed in (let's say "b") had been modified and
passed as a result. Thus operator overloads for classes can easily lead to
memory leaks or other hard to debug problems. Yes, that's already possible
with global operators as well, but with operators that are part of the
class that would be much more inviting.

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

Re: [fpc-pascal] Subclassing generic records?

2017-07-21 Thread Ryan Joseph
Thanks Sven, that’s one way around it. 

So is it by design that records don’t have inheritance or is this planned? 

and is it also by design that classes don’t allow operator overloads inside 
them? That seems like an omission since the way they’re implemented in records 
is much nicer imo.

> On Jul 20, 2017, at 4:11 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> I have also another solution for your original problem. Take this code:

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Subclassing generic records?

2017-07-20 Thread Sven Barth via fpc-pascal
On 17.07.2017 19:20, Ryan Joseph wrote:
> 
>> On Jul 17, 2017, at 10:58 AM, Sven Barth via fpc-pascal 
>>  wrote:
>>
>> I'll need to check whether Delphi allows that for helpers (doesn't matter 
>> whether the extended type is a specialization or not).
>>
>>
> 
> Thanks Sven. Records/objects/classes in Pascal feel very confused right now. 
> Records are moving in the direction of legacy style “objects” which are 
> allocated on the stack so I wonder why objects just don’t replace records 
> already? Having said that why don’t classes just replace records/objects 
> except they allocate on the stack? These 3 distinct constructs don’t really 
> make sense more imo.

First of records can't replace objects, because objects have inheritance
and a VMT for virtual methods not to mention destructors. Secondly this
would lead to all kind of backwards compatibility problems.
Classes are not designed to be allocated on the stack. They are only on
the heap, thus they are a different kind of beast to records and objects.
And records - unlike objects and classes - can have operator overloads
*inside* of them which allows this operators to be used inside generic
specializations.

I have also another solution for your original problem. Take this code:

=== code begin ===

program trechelpfld;

{$mode objfpc}
{$modeswitch advancedrecords}

type
  TTest = record
x, y: Double;
  end;

  TTestHelper = record helper for TTest
  private
function GetWidth: Double; inline;
function GetHeight: Double; inline;
procedure SetWidth(aValue: Double); inline;
procedure SetHeight(aValue: Double); inline;
  public
property Width: Double read GetWidth write SetWidth;
property Height: Double read GetHeight write SetHeight;
  end;

function TTestHelper.GetWidth: Double;
begin
  Result := x;
end;

function TTestHelper.GetHeight: Double;
begin
  Result := y;
end;

procedure TTestHelper.SetWidth(aValue: Double);
begin
  x := aValue;
end;

procedure TTestHelper.SetHeight(aValue: Double);
begin
  y := aValue;
end;

var
  t: TTest;
  x, y: Double;
begin
  t.x := 42.0;
  t.y := 21.0;

  x := t.Width;
  y := t.Height;

  t.Width := y;
  t.Height := x;
end.

=== code end ===

Through the use of "inline" this results in code without calls as the
assembly output of the main procedure without any optimizations shows:

=== code begin ===

.section .text.n_main
.balign 16,0x90
.globl  PASCALMAIN
.type   PASCALMAIN,@function
PASCALMAIN:
.globl  main
.type   main,@function
main:
.Lc21:
# Temps allocated between rbp-16 and rbp+0
# [45] begin
pushq   %rbp
.Lc23:
.Lc24:
movq%rsp,%rbp
.Lc25:
leaq-16(%rsp),%rsp
callFPC_INITIALIZEUNITS
# [46] t.x := 42.0;
movq_$TRECHELPFLD$_Ld1,%rax
movq%rax,U_$P$TRECHELPFLD_$$_T
# [47] t.y := 21.0;
movq_$TRECHELPFLD$_Ld2,%rax
movq%rax,U_$P$TRECHELPFLD_$$_T+8
# [49] x := t.Width;
movsd   U_$P$TRECHELPFLD_$$_T,%xmm0
movsd   %xmm0,U_$P$TRECHELPFLD_$$_X
# [50] y := t.Height;
movsd   U_$P$TRECHELPFLD_$$_T+8,%xmm0
movsd   %xmm0,U_$P$TRECHELPFLD_$$_Y
# [52] t.Width := y;
movqU_$P$TRECHELPFLD_$$_Y,%rax
movq%rax,U_$P$TRECHELPFLD_$$_T
# [53] t.Height := x;
movqU_$P$TRECHELPFLD_$$_X,%rax
movq%rax,U_$P$TRECHELPFLD_$$_T+8
# [54] end.
callFPC_DO_EXIT
leave
ret
.Lc22:
.Le4:
.size   main, .Le4 - main

=== code end ===

It might be more to write, but it works...

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

Re: [fpc-pascal] Subclassing generic records?

2017-07-17 Thread Ryan Joseph

> On Jul 17, 2017, at 10:58 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> I'll need to check whether Delphi allows that for helpers (doesn't matter 
> whether the extended type is a specialization or not).
> 
> 

Thanks Sven. Records/objects/classes in Pascal feel very confused right now. 
Records are moving in the direction of legacy style “objects” which are 
allocated on the stack so I wonder why objects just don’t replace records 
already? Having said that why don’t classes just replace records/objects except 
they allocate on the stack? These 3 distinct constructs don’t really make sense 
more imo.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Subclassing generic records?

2017-07-17 Thread Sven Barth via fpc-pascal
Am 17.07.2017 18:24 schrieb "Ryan Joseph" :
>
> I’m trying to find a way to extend generic records since (as far as I
know) there is no subclassing of records. I could use variant records here
but these don’t work with generics so I tried record helpers and properties
to basically rename the x/y variables in TVec2 but I get errors on the
width/height properties. Is there a workaround for this?
>
> type
> generic TVec2 = record
> public
> x, y: T;
> end;
> type
> TSize = specialize TVec2;
> type
> TVec2Size = record helper for TSize
> property Width: TFloat read x write x;
> property Height: TFloat read y write y;
> end;

I'll need to check whether Delphi allows that for helpers (doesn't matter
whether the extended type is a specialization or not).

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