Re: [fpc-pascal] Default record const values

2018-11-28 Thread Ryan Joseph


> On Nov 29, 2018, at 2:27 AM, Benjamin Rosseaux  wrote:
> 
> TTestHelper = record helper for TTest
>   public
> const Default: TTest = (a: 1; b: 2);
>   end;

I didn’t even know you could add consts to record helpers. That’s good to know, 
thanks.

Multi scoped helpers will make this a safe solution which you don’t have to 
worry about being overwritten in other units. Hopefully I can submit a patch 
for the trunk soon.

Regards,
Ryan Joseph

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Ryan Joseph


> On Nov 28, 2018, at 11:25 PM, Sven Barth via fpc-pascal 
>  wrote:
> 
> You're not wrong, but a type alias is definitely the wrong way. 
> But that is a completely different topic, one that I'm not willing to discuss 
> right now, aside from "we don't support something like that”.

Ok, maybe something to think about later. Compile time performance could be a 
reason to pursue down the road.

> If all that’s involved is comparing params types to generic types then that 
> looks like a relatively simple solution.  Const generic params may have 
> complicated this some however.
> 
> Yes, all generic parameters need to be part of the routine's parameters and 
> constant parameters indeed won't work in that case. 

What are the performance implications of specializing all these types across a 
code base? I’ve heard c++ developers mention the terrible performance of 
templates and I think that’s because of the inferred types and inability to 
specialize once (like FPC does for all other generics except procs).

Looking at this now I think that each unit that uses an inferred specialization 
will produce a unit procedure for just that unit. Is that right?

Here’s an example which specializes 3 generics (they’re shared right?) across 5 
procedure calls.

generic procedure DoThis(msg:T);
begin
end;

generic procedure DoThis(msg:T;param1:T);
begin
end;

generic procedure DoThis(msg:T;param1:integer);
begin
end;

begin
DoThis('hello');// specialize DoThis('hello');
DoThis(1);  // specialize DoThis(1);
DoThis('a','b');// specialize DoThis('a','b’);
DoThis(1,1);// specialize DoThis(1,1);
DoThis('hello',1);  // specialize DoThis(‘hello',1);

Regards,
Ryan Joseph

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Ryan Joseph


> On Nov 29, 2018, at 5:15 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> Looks better.
> The next thing to nuke is the tgenericparamdef. The parameters stored in 
> tdef.genericparas are the parameter symbols, so there should be no need for 
> defs. If necessary some of the code in pgenutil (and related functions) will 
> need to be changed from handling a list of defs to a list of syms.

I added that extra type so that it would be compatible with genericdeflist. I 
don’t see how that can be removed. The const sym is pulled out in 
generate_specialization_phase2 and renamed (which I forget why already).

So the tgenericparamdef is just a vessel to hold the constsym until 
generate_specialization_phase2? Either way removing it means breaking 
genericdeflist right?

if typeparam.nodetype <> typen then
  begin
{ the typesym from paramdef will be added to the list in 
generate_specialization_phase2 }
paramdef := 
tgenericparamdef.create(typeparam.resultdef,typeparam,constprettyname);
genericdeflist.Add(paramdef);
  end
else
  begin
constprettyname := '';
genericdeflist.Add(typeparam.resultdef);
  end;

from generate_specialization_phase2:

for i:=0 to genericdef.genericparas.Count-1 do
  begin
srsym:=tsym(genericdef.genericparas[i]);
if not (sp_generic_para in srsym.symoptions) then
  internalerror(2013092602);

// note: ryan
{ set the generic param name of the constsym of tgenericparamdef }
typedef := tstoreddef(context.genericdeflist[i]);
if typedef.typ = genericconstdef then
  tgenericparamdef(typedef).typesym.realname := srsym.realname;

generictypelist.add(srsym.realname,typedef.typesym);
  end;

Regards,
Ryan Joseph

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Sven Barth via fpc-pascal

Am 27.11.2018 um 11:35 schrieb Sven Barth:
Am Di., 27. Nov. 2018, 08:18 hat Ryan Joseph 
mailto:r...@thealchemistguild.com>> 
geschrieben:




> On Nov 27, 2018, at 4:59 AM, Sven Barth via fpc-pascal
mailto:fpc-pascal@lists.freepascal.org>> wrote:
>
> Best check again once you've done the switch to tconstsym for
constants. :)
>

I made most of the changes you mentioned so please look. Including
the constsyms didn’t break anything and helped to clean up the
code. I would have done that from the start but I wasn’t sure you
wanted me mixing in new types.


Good, thank you. Hopefully I'll find the time this evening to look at 
your changes again. :)


Looks better.
The next thing to nuke is the tgenericparamdef. The parameters stored in 
tdef.genericparas are the parameter symbols, so there should be no need 
for defs. If necessary some of the code in pgenutil (and related 
functions) will need to be changed from handling a list of defs to a 
list of syms.


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

Re: [fpc-pascal] Default record const values

2018-11-28 Thread Benjamin Rosseaux
I'm using this solution myself for the vector and matrix data types at

https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.pas
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector2.Swizzle.Definitions.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector2.Swizzle.Implementations.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector2Helper.Swizzle.Definitions.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector2Helper.Swizzle.Implementations.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector3.Swizzle.Definitions.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector3.Swizzle.Implementations.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector3Helper.Swizzle.Definitions.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector3Helper.Swizzle.Implementations.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector4.Swizzle.Definitions.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector4.Swizzle.Implementations.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector4Helper.Swizzle.Definitions.inc
https://github.com/BeRo1985/pasvulkan/blob/master/src/PasVulkan.Math.TpvVector4Helper.Swizzle.Implementations.inc

without any bigger issues, except that the Delphi IDE has some runtime
CodeInsight record lookup issues from time to time.


On Wed, Nov 28, 2018 at 8:47 PM Sven Barth via fpc-pascal <
fpc-pascal@lists.freepascal.org> wrote:

> Am 28.11.2018 um 20:27 schrieb Benjamin Rosseaux:
>
> program Test123;
> {$ifdef fpc}
>   {$mode delphi}
> {$endif}
>
> type
>   TTest = record
>   public
> a: LongInt;
> b: LongInt;
>   end;
>
>   TTestHelper = record helper for TTest
>   public
> const Default: TTest = (a: 1; b: 2);
>   end;
>
> var
>   Test: TTest;
> begin
>   Test := TTest.Default;
> end.
>
> That is indeed a good idea and with the extension to allow multiple
> helpers there wouldn't even be a negative impact... 樂
>
> Regards,
> Sven
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Default record const values

2018-11-28 Thread Sven Barth via fpc-pascal

Am 28.11.2018 um 20:27 schrieb Benjamin Rosseaux:

program Test123;
{$ifdef fpc}
  {$mode delphi}
{$endif}

type
  TTest = record
  public
    a: LongInt;
    b: LongInt;
  end;

  TTestHelper = record helper for TTest
  public
    const Default: TTest = (a: 1; b: 2);
  end;

var
  Test: TTest;
begin
  Test := TTest.Default;
end.

That is indeed a good idea and with the extension to allow multiple 
helpers there wouldn't even be a negative impact... 樂


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

Re: [fpc-pascal] Default record const values

2018-11-28 Thread Benjamin Rosseaux
program Test123;
{$ifdef fpc}
  {$mode delphi}
{$endif}

type
  TTest = record
  public
a: LongInt;
b: LongInt;
  end;

  TTestHelper = record helper for TTest
  public
const Default: TTest = (a: 1; b: 2);
  end;

var
  Test: TTest;
begin
  Test := TTest.Default;
end.

On Sat, Nov 10, 2018 at 10:06 AM Ryan Joseph 
wrote:

> Should’t this work? This would be a good way to set default record values
> but it doesn’t seem to be supported.
>
>
> type
> TMyRecord = record
> public
> a: integer;
> b: string;
> const
> default: TMyRecord = (a: 100; b: 'foo');
> end;
>
> var
> r: TMyRecord = TMyRecord.default;
>
>
> Regards,
> Ryan Joseph
>
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Sven Barth via fpc-pascal
Am Mi., 28. Nov. 2018, 15:27 hat Ryan Joseph 
geschrieben:

>
>
> > On Nov 28, 2018, at 7:26 PM, Sven Barth via fpc-pascal <
> fpc-pascal@lists.freepascal.org> wrote:
> >
> > Because that is not supposed to work. Generic routines are *routines*,
> not types. You can't define aliases for routines either, not to mention the
> problems with scoping as generic methods exist as well.
>
> It seems natural you could specialize a generic procedure because you can
> do this for all other generic types. Maybe a type isn’t the right way but
> it feels like there should be some way to specialize the procedure header
> outside of a begin/end block. I know you can't make aliases to procedures
> but generics are more of “instantiating a template” which falls outside the
> scope the language in general.
>

You're not wrong, but a type alias is definitely the wrong way.
But that is a completely different topic, one that I'm not willing to
discuss right now, aside from "we don't support something like that".


> >
> > Generic routines however have a different boon in Delphi that I plan to
> add as well: inference of the type parameters based on the parameters the
> user passed. In that case the type parameter clause as well as the
> "specialize" in non-Delphi modes would not need to be used and it would
> look like a normal, non-generic call.
>
> That’s probably the best way (Swift does this and I always wondered why
> FPC doesn’t) but it won’t work unless the parameters contain the generic
> parameter, which is a minority of generics functions anyways.
>
> Just to be sure, you mean like this?
>
> generic procedure DoThis(msg:T);
> begin
> end;
>
> begin
>
> DoThis(‘hello’); // compiles as “specialize
> DoThis(‘hello’)” because param types match generic parameter types
>
> If all that’s involved is comparing params types to generic types then
> that looks like a relatively simple solution.  Const generic params may
> have complicated this some however.
>

Yes, all generic parameters need to be part of the routine's parameters and
constant parameters indeed won't work in that case.

Regards,
Sven

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Ryan Joseph


> On Nov 28, 2018, at 7:26 PM, Sven Barth via fpc-pascal 
>  wrote:
> 
> Because that is not supposed to work. Generic routines are *routines*, not 
> types. You can't define aliases for routines either, not to mention the 
> problems with scoping as generic methods exist as well. 

It seems natural you could specialize a generic procedure because you can do 
this for all other generic types. Maybe a type isn’t the right way but it feels 
like there should be some way to specialize the procedure header outside of a 
begin/end block. I know you can't make aliases to procedures but generics are 
more of “instantiating a template” which falls outside the scope the language 
in general.

> 
> Generic routines however have a different boon in Delphi that I plan to add 
> as well: inference of the type parameters based on the parameters the user 
> passed. In that case the type parameter clause as well as the "specialize" in 
> non-Delphi modes would not need to be used and it would look like a normal, 
> non-generic call. 

That’s probably the best way (Swift does this and I always wondered why FPC 
doesn’t) but it won’t work unless the parameters contain the generic parameter, 
which is a minority of generics functions anyways.
 
Just to be sure, you mean like this?

generic procedure DoThis(msg:T);
begin
end;

begin

DoThis(‘hello’); // compiles as “specialize DoThis(‘hello’)” 
because param types match generic parameter types

If all that’s involved is comparing params types to generic types then that 
looks like a relatively simple solution.  Const generic params may have 
complicated this some however.

Regards,
Ryan Joseph

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Sven Barth via fpc-pascal
Am Mi., 28. Nov. 2018, 09:41 hat Ryan Joseph 
geschrieben:

> I just noticed I sent this to the wrong person and the list never saw it
> so I’m sending it again. I feel like I should try to fix it while I’ve got
> my eyes on the generics code before I forget.
>
> Is there a reason it’s not implemented yet? In theory you should be able
> to specialize a function as a type and use the type name as the function
> name. This is basically the same syntax for class construction but without
> the .create.
>
> 
>
> As a side node I haven’t been willing to use generic functions yet because
> the syntax is so verbose it kind of defeats the purpose.
>
> Why can’t we specialize functions as a type? Maybe that’s on the todo list
> also?
>

Because that is not supposed to work. Generic routines are *routines*, not
types. You can't define aliases for routines either, not to mention the
problems with scoping as generic methods exist as well.

Generic routines however have a different boon in Delphi that I plan to add
as well: inference of the type parameters based on the parameters the user
passed. In that case the type parameter clause as well as the "specialize"
in non-Delphi modes would not need to be used and it would look like a
normal, non-generic call.

Regards,
Sven

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Ryan Joseph


> On Nov 27, 2018, at 11:07 PM, Sven Barth via fpc-pascal 
>  wrote:
> 
> Does it also work correctly if you change the constant and then recompile? 
> The same if the specialization is inside another unit used by the program? 
> 

It appears to work. I’ll make a proper test suite once we have the basics 
settled.

Regards,
Ryan Joseph

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

Re: [fpc-pascal] Constants in generics

2018-11-28 Thread Ryan Joseph
I just noticed I sent this to the wrong person and the list never saw it so I’m 
sending it again. I feel like I should try to fix it while I’ve got my eyes on 
the generics code before I forget. 

Is there a reason it’s not implemented yet? In theory you should be able to 
specialize a function as a type and use the type name as the function name. 
This is basically the same syntax for class construction but without the 
.create.



As a side node I haven’t been willing to use generic functions yet because the 
syntax is so verbose it kind of defeats the purpose.

Why can’t we specialize functions as a type? Maybe that’s on the todo list also?

generic procedure DoThis(msg:string);
begin
writeln(msg, ' ',sizeof(T));
end;

type
DoInt = specialize DoThis;

begin
DoInt(‘hello');

Regards,
Ryan Joseph

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