Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-28 Thread Benito van der Zander

Hi,




Also assume you have a record and a hashmap that stores them. Now you 
add a string to the record which turns it into a managed one and 
suddenly your code will no longer work, probably resulting in subtle 
bugs or memory leaks. That's /not/ what should happen for merely 
adding a string. It's already bad enough that this happens with the 
Pascal style I/O we don't need to have this with base container types.


For calling Free we have explicit classes. But the difference between 
managed types vs. not-managed types is subtle and can change - as 
mentioned above - by merely adding a field.


That is why FreePascal should merge non-managed generic classes that 
have the same size when it can.


But as long as FreePascal does not do it, the user needs to do the 
merging manually, with all the resulting problems. And constants 
generics can be used to store the size


Best,
Benito
On 27.04.20 07:46, Sven Barth wrote:

Am 26.04.2020 um 23:42 schrieb Benito van der Zander:

Hi Sven,



It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


I mostly use generics for containers, especially hashmaps. They only 
stores the values and never calls specific methods on them




Well, nice and well for /you/ then, but there are many more uses for 
generics. And as a compiler developer I /must/ think about these cases 
as well.





Not to mention that your TBaseHashMap would not work with managed 
types...


That would need be handled separately. There are probably also people 
who want a container that calls .free on TObject descendants.


The user should not need to care about that, especially for general 
base classes.


Also assume you have a record and a hashmap that stores them. Now you 
add a string to the record which turns it into a managed one and 
suddenly your code will no longer work, probably resulting in subtle 
bugs or memory leaks. That's /not/ what should happen for merely 
adding a string. It's already bad enough that this happens with the 
Pascal style I/O we don't need to have this with base container types.


For calling Free we have explicit classes. But the difference between 
managed types vs. not-managed types is subtle and can change - as 
mentioned above - by merely adding a field.


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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-27 Thread Sven Barth via fpc-devel
Ryan Joseph via fpc-devel  schrieb am Mo.,
27. Apr. 2020, 18:28:

> I think constants in generics may be the only way to create dynamically
> sized types at compile time (via static arrays). That seems like a really
> narrow usage but it opens a lot of doors most of us have probably never
> thought about. I suspect in time more good usages will be discovered.
>

That's what I think 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] New feature announcement: constant parameters for generics

2020-04-27 Thread Ryan Joseph via fpc-devel
I think constants in generics may be the only way to create dynamically sized 
types at compile time (via static arrays). That seems like a really narrow 
usage but it opens a lot of doors most of us have probably never thought about. 
I suspect in time more good usages will be discovered.

Regards,
Ryan Joseph

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Sven Barth via fpc-devel

Am 26.04.2020 um 23:42 schrieb Benito van der Zander:

Hi Sven,



It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


I mostly use generics for containers, especially hashmaps. They only 
stores the values and never calls specific methods on them




Well, nice and well for /you/ then, but there are many more uses for 
generics. And as a compiler developer I /must/ think about these cases 
as well.





Not to mention that your TBaseHashMap would not work with managed 
types...


That would need be handled separately. There are probably also people 
who want a container that calls .free on TObject descendants.


The user should not need to care about that, especially for general base 
classes.


Also assume you have a record and a hashmap that stores them. Now you 
add a string to the record which turns it into a managed one and 
suddenly your code will no longer work, probably resulting in subtle 
bugs or memory leaks. That's /not/ what should happen for merely adding 
a string. It's already bad enough that this happens with the Pascal 
style I/O we don't need to have this with base container types.


For calling Free we have explicit classes. But the difference between 
managed types vs. not-managed types is subtle and can change - as 
mentioned above - by merely adding a field.


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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Kai Burghardt
Hey folks!

On Sun, Apr 26, 2020 at 03:09:43PM +0700, Ryan Joseph via fpc-devel wrote:
> It was meant for a pretty narrow use of array types. [...]

If so, can I finally have my Extended Pascal schemata?

https://wiki.freepascal.org/Extended_Pascal#Schemata_.28not_yet_implemented.29

It's basically the same, isn't it? Just a different syntax.

[For reference: http://www.pascal-central.com/docs/iso10206.pdf (§ 6.4.7, PDF 
page 53)]
-- 
Sincerely yours
Kai Burghardt


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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Marco van de Voort


Op 2020-04-26 om 11:48 schreef Sven Barth via fpc-devel:


Jeppe had provided a potential usecase on the core mailing list in 
October '18. His example is not useable as-is, but to give you an idea:


 As the compiler can inline all this, the writing of maintainable, 
hardware agnostic frameworks for embedded controllers becomes easier.


(Actually you'd probably want to use atomic RMW operations, because 
otherwise a write from a thread or interrupt routine could be 
overwritten, even if it was not on bits that clash)


A further example could be to determine the size of a hash table: 
Determining that at compile time instead of runtime might allow for 
better code. At the same time the user of that code would still be 
able to influence it.


Yup. My Genlight sorted stringlist could also use it for tuning. To 
workaround the classic tstringlist ordered insertion limit, it uses an 
(dyn) array of small arrays to store the strings, which postpones the 
inevitable with about a magnitude 10-20.


The constant would be the size of the deeper array, now a weighted value 
1024.


Larger (e.g. 4096) means less memory overhead, faster iteration, but 
with slower (random) insertion performance, which can be perfectly fine 
if your datasource is mostly in order + few mutations.



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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Benito van der Zander

Hi Sven,



It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


I mostly use generics for containers, especially hashmaps. They only 
stores the values and never calls specific methods on them





Not to mention that your TBaseHashMap would not work with managed types...


That would need be handled separately. There are probably also people 
who want a container that calls .free on TObject descendants.



Best,
Benito
On 26.04.20 14:18, Sven Barth wrote:

Am 26.04.2020 um 14:01 schrieb Benito van der Zander:

Hi,

perhaps it could be used to merge specializations (if fpc cannot do 
that on its own):


Like when you have a hashmap THashMap, and need three 
specializations:


THashMap

THashMap

THashMap

It is basically three times the same hashmap, but if fpc does not 
detect that, it might generate three times the same assembly code, 
which waste a lot of space.



But with constants it can be merged to TBaseHashMapinteger> and then you only have one map in the assembly code, and 
three wrappers to remove the casting:


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap




It's not that simple. In principle you're right that the compiler 
could try to merge more implementations, but this does not depend on 
the declaration of the generic, but the use of the parameter types.


Take the following example:

=== code begin ===

{$mode objfpc}

type
  generic TTest = class
    procedure DoSomething;
  end;

  TMyClass1 = class
 procedure Foobar;
  end;

  TMyClass2 = class
    procedure Foobar; virtual;
  end;

procedure TTest.DoSomething;
var
  o: T;
begin
  o.Foobar;
end;

procedure TMyClass1.Foobar;
begin
  Writeln('TMyClass1.Foobar');
end;

procedure TMyClass2.Foobar;
begin
  Writeln('TMyClass2.Foobar');
end;

type
  TTestMyClass1 = specialize TTest;
  TTestMyClass2 = specialize TTest;

begin
end.

=== code end ===

In case of TMyClass1 this will result in a static call to 
TMyClass1.Foobar, however in case of TMyClass2 this will result in an 
indirect call through the VMT.


The type information needs to be correct as well, even more so once we 
have support for Extended RTTI where one can enumerate non-published 
fields, properties and methods in addition to published.


Not to mention that your TBaseHashMap would not work with managed types...

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Marco van de Voort


Op 2020-04-26 om 11:02 schreef Michael Van Canneyt:


As the original author, can you say something about the intended use 
of this feature ?


It was meant for a pretty narrow use of array types. If I knew how 
much work it would be to implement I probably would have not done it. 
:P I personally wanted it for static array lists that had methods 
like Add/Delete.


Fixed-length arrays are the only practical use I can think of.


Valuetype sets of enum>256 elements.  Type T is the enum, const is 
ord(high(enum) div 32)+1


De const is then a high bound of the array, type T is only used to 
implement the operators and methods.



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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Ben Grasset via fpc-devel
On Sun, Apr 26, 2020 at 4:08 AM Anthony Walter via fpc-devel <
fpc-devel@lists.freepascal.org> wrote:

> Thank you Ryan and Sven. Your work is much appreciated as usual.
>
> However, Michael beat me to it in asking how this feature is useful. I am
> sure there might be use cases, but for right now I am coming up without any
> real advantages. Could anyone with better insight than me please explain?
>

A simple, but IMO exciting use case is just that it can provide
impossible-to-achieve-otherwise optimizations via const propagation.

For example, some functions and procedures that used to have to take
numerical values as regular parameters can now instead take them as generic
constant parameters, which allows the compiler to "carry them farther" than
it ever would have previously.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Ben Grasset via fpc-devel
On Sat, Apr 25, 2020 at 6:14 PM Sven Barth via fpc-devel <
fpc-devel@lists.freepascal.org> wrote:

> The Free Pascal team is happy to announce the addition of a new language
> feature: constant parameters for generics.
>

YES! This is fantastic news.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Sven Barth via fpc-devel

Am 26.04.2020 um 14:01 schrieb Benito van der Zander:

Hi,

perhaps it could be used to merge specializations (if fpc cannot do 
that on its own):


Like when you have a hashmap THashMap, and need three 
specializations:


THashMap

THashMap

THashMap

It is basically three times the same hashmap, but if fpc does not 
detect that, it might generate three times the same assembly code, 
which waste a lot of space.



But with constants it can be merged to TBaseHashMapinteger> and then you only have one map in the assembly code, and 
three wrappers to remove the casting:


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap




It's not that simple. In principle you're right that the compiler could 
try to merge more implementations, but this does not depend on the 
declaration of the generic, but the use of the parameter types.


Take the following example:

=== code begin ===

{$mode objfpc}

type
  generic TTest = class
    procedure DoSomething;
  end;

  TMyClass1 = class
 procedure Foobar;
  end;

  TMyClass2 = class
    procedure Foobar; virtual;
  end;

procedure TTest.DoSomething;
var
  o: T;
begin
  o.Foobar;
end;

procedure TMyClass1.Foobar;
begin
  Writeln('TMyClass1.Foobar');
end;

procedure TMyClass2.Foobar;
begin
  Writeln('TMyClass2.Foobar');
end;

type
  TTestMyClass1 = specialize TTest;
  TTestMyClass2 = specialize TTest;

begin
end.

=== code end ===

In case of TMyClass1 this will result in a static call to 
TMyClass1.Foobar, however in case of TMyClass2 this will result in an 
indirect call through the VMT.


The type information needs to be correct as well, even more so once we 
have support for Extended RTTI where one can enumerate non-published 
fields, properties and methods in addition to published.


Not to mention that your TBaseHashMap would not work with managed types...

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Benito van der Zander

Hi,

perhaps it could be used to merge specializations (if fpc cannot do that 
on its own):


Like when you have a hashmap THashMap, and need three 
specializations:


THashMap

THashMap

THashMap

It is basically three times the same hashmap, but if fpc does not detect 
that, it might generate three times the same assembly code, which waste 
a lot of space.



But with constants it can be merged to TBaseHashMapinteger> and then you only have one map in the assembly code, and three 
wrappers to remove the casting:


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap


THashMap = TBaseHashMap = 
TBaseHashMap




Cheers,
Benito
On 26.04.20 11:48, Sven Barth via fpc-devel wrote:

Am 26.04.2020 um 09:38 schrieb Michael Van Canneyt:



On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:




On Apr 26, 2020, at 5:13 AM, Sven Barth via fpc-devel 
 wrote:


The Free Pascal team is happy to announce the addition of a new 
language feature: constant parameters for generics.


Excellent! Thanks for getting this merged. It was a long battle but 
it's finally over. ;)


As the original author, can you say something about the intended use 
of this feature ?


Sven gave some examples, and they show how it works, but from his 
examples I don't see the point

of this feature.


Jeppe had provided a potential usecase on the core mailing list in 
October '18. His example is not useable as-is, but to give you an idea:


=== code begin ===

program tgpio;

{$mode objfpc}
{$modeswitch advancedrecords}

type
 generic TSomeMicroGPIO = record
 private
   procedure SetPin(aIndex: SizeInt; aEnable: Boolean); inline;
   function GetPin(aIndex: SizeInt): Boolean; inline;
 public
   property Pin[Index: SizeInt]: Boolean read GetPin write SetPin;
 end;

procedure TSomeMicroGPIO.SetPin(aIndex: SizeInt; aEnable: Boolean);
begin
  if aEnable then
    PLongWord(Base)[2] := PLongWord(Base)[2] or (1 shl aIndex)
  else
    PLongWord(Base)[2] := PLongWord(Base)[2] and not (1 shl aIndex);
end;

function TSomeMicroGPIO.GetPin(aIndex: SizeInt): Boolean;
begin
  Result := (PLongWord(Base)[2] and (1 shl aIndex)) <> 0
end;

var
  GPIOA: specialize TSomeMicroGPIO<$8000F000>;
  GPIOB: specialize TSomeMicroGPIO<$8000F100>;
  GPIOC: specialize TSomeMicroGPIO<$8000F200>;

begin
  GPIOA.Pin[2] := True;
end.

=== code end ===

As the compiler can inline all this, the writing of maintainable, 
hardware agnostic frameworks for embedded controllers becomes easier.


In general I agree with you that the use of constants as generic 
parameters is less wide. But there cases where one might want them.


A further example could be to determine the size of a hash table: 
Determining that at compile time instead of runtime might allow for 
better code. At the same time the user of that code would still be 
able to influence it.


In the bug report there was a further example by Akira1364. At its 
core it's about static arrays again, but it shows what can be done 
with this:


=== code begin ===

program ConstMatrixExampleObjFPC;

{$mode ObjFPC}
{$modeswitch AdvancedRecords}

type
  String3 = String[3];

  generic TRawMatrix = array[0..N-1] of 
array[0..N-1] of T;


  generic TMatrix = record
  private type
ArrayType = specialize TRawMatrix;
  private
Data: ArrayType;
  public
class operator :=(constref Arr: ArrayType): TMatrix; inline;
procedure Display;
  end;

  class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
  begin
Result.Data := Arr;
  end;

  procedure TMatrix.Display;
  var I, J: SizeInt;
  begin
WriteLn('[');
for I := 0 to N - 1 do begin
  Write(' [');
  for J := 0 to N - 2 do
Write(Data[I, J], ', ');
  Write(Data[I, N - 1]);
  Writeln('] ');
end;
Write(']');
  end;

const RawMat: specialize TRawMatrix = (
  ('AAA', 'BBB', 'CCC', 'DDD'),
  ('EEE', 'FFF', 'GGG', 'HHH'),
  ('III', 'JJJ', 'KKK', 'LLL'),
  ('MMM', 'NNN', 'OOO', 'PPP')
);

var Mat: specialize TMatrix;

begin
  Mat := RawMat;
  Mat.Display();
end.

=== code end ===

I'm sure the future will show more potential examples. Or one could 
look at C++ examples that allow constants as well.


Regards,
Sven
___
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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Sven Barth via fpc-devel

Am 26.04.2020 um 09:38 schrieb Michael Van Canneyt:



On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:




On Apr 26, 2020, at 5:13 AM, Sven Barth via fpc-devel 
 wrote:


The Free Pascal team is happy to announce the addition of a new 
language feature: constant parameters for generics.


Excellent! Thanks for getting this merged. It was a long battle but 
it's finally over. ;)


As the original author, can you say something about the intended use 
of this feature ?


Sven gave some examples, and they show how it works, but from his 
examples I don't see the point

of this feature.


Jeppe had provided a potential usecase on the core mailing list in 
October '18. His example is not useable as-is, but to give you an idea:


=== code begin ===

program tgpio;

{$mode objfpc}
{$modeswitch advancedrecords}

type
 generic TSomeMicroGPIO = record
 private
   procedure SetPin(aIndex: SizeInt; aEnable: Boolean); inline;
   function GetPin(aIndex: SizeInt): Boolean; inline;
 public
   property Pin[Index: SizeInt]: Boolean read GetPin write SetPin;
 end;

procedure TSomeMicroGPIO.SetPin(aIndex: SizeInt; aEnable: Boolean);
begin
  if aEnable then
    PLongWord(Base)[2] := PLongWord(Base)[2] or (1 shl aIndex)
  else
    PLongWord(Base)[2] := PLongWord(Base)[2] and not (1 shl aIndex);
end;

function TSomeMicroGPIO.GetPin(aIndex: SizeInt): Boolean;
begin
  Result := (PLongWord(Base)[2] and (1 shl aIndex)) <> 0
end;

var
  GPIOA: specialize TSomeMicroGPIO<$8000F000>;
  GPIOB: specialize TSomeMicroGPIO<$8000F100>;
  GPIOC: specialize TSomeMicroGPIO<$8000F200>;

begin
  GPIOA.Pin[2] := True;
end.

=== code end ===

As the compiler can inline all this, the writing of maintainable, 
hardware agnostic frameworks for embedded controllers becomes easier.


In general I agree with you that the use of constants as generic 
parameters is less wide. But there cases where one might want them.


A further example could be to determine the size of a hash table: 
Determining that at compile time instead of runtime might allow for 
better code. At the same time the user of that code would still be able 
to influence it.


In the bug report there was a further example by Akira1364. At its core 
it's about static arrays again, but it shows what can be done with this:


=== code begin ===

program ConstMatrixExampleObjFPC;

{$mode ObjFPC}
{$modeswitch AdvancedRecords}

type
  String3 = String[3];

  generic TRawMatrix = array[0..N-1] of 
array[0..N-1] of T;


  generic TMatrix = record
  private type
ArrayType = specialize TRawMatrix;
  private
Data: ArrayType;
  public
class operator :=(constref Arr: ArrayType): TMatrix; inline;
procedure Display;
  end;

  class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
  begin
Result.Data := Arr;
  end;

  procedure TMatrix.Display;
  var I, J: SizeInt;
  begin
WriteLn('[');
for I := 0 to N - 1 do begin
  Write(' [');
  for J := 0 to N - 2 do
Write(Data[I, J], ', ');
  Write(Data[I, N - 1]);
  Writeln('] ');
end;
Write(']');
  end;

const RawMat: specialize TRawMatrix = (
  ('AAA', 'BBB', 'CCC', 'DDD'),
  ('EEE', 'FFF', 'GGG', 'HHH'),
  ('III', 'JJJ', 'KKK', 'LLL'),
  ('MMM', 'NNN', 'OOO', 'PPP')
);

var Mat: specialize TMatrix;

begin
  Mat := RawMat;
  Mat.Display();
end.

=== code end ===

I'm sure the future will show more potential examples. Or one could look 
at C++ examples that allow constants 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] New feature announcement: constant parameters for generics

2020-04-26 Thread Ryan Joseph via fpc-devel


> On Apr 26, 2020, at 4:02 PM, Michael Van Canneyt  
> wrote:
> 
> Fixed-length arrays are the only practical use I can think of.

I think you're right. Here's what I'll say next time: They're for composing 
types of dynamic size at compile time. :)

Regards,
Ryan Joseph

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Florian Klaempfl

Am 26.04.2020 um 11:02 schrieb Michael Van Canneyt:



On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:




On Apr 26, 2020, at 2:38 PM, Michael Van Canneyt 
 wrote:


As the original author, can you say something about the intended use 
of this feature ?


It was meant for a pretty narrow use of array types. If I knew how 
much work it would be to implement I probably would have not done it. 
:P I personally wanted it for static array lists that had methods like 
Add/Delete.


Fixed-length arrays are the only practical use I can think of.

The record with constants example is too convoluted to my taste.
As a reader, I find such code hard to understand.

Thanks for the examples !


Another example might be headers for embedded systems.

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Michael Van Canneyt



On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:





On Apr 26, 2020, at 2:38 PM, Michael Van Canneyt  wrote:

As the original author, can you say something about the intended use of this 
feature ?


It was meant for a pretty narrow use of array types. If I knew how much work it 
would be to implement I probably would have not done it. :P I personally wanted 
it for static array lists that had methods like Add/Delete.


Fixed-length arrays are the only practical use I can think of.

The record with constants example is too convoluted to my taste.
As a reader, I find such code hard to understand.

Thanks for the examples !

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread gabor

W dniu 2020-04-26 o 09:38, Michael Van Canneyt pisze:
Sven gave some examples, and they show how it works, but from his 
examples I don't see the point

of this feature.

Michael.


It can be quite useful. You can do something similar (I hope):
https://sourceforge.net/p/ultravnc/code/HEAD/tree/UltraVNC%20Project%20Root/UltraVNC/vncviewer/ClientConnectionHextile.cpp

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Ryan Joseph via fpc-devel


> On Apr 26, 2020, at 2:38 PM, Michael Van Canneyt  
> wrote:
> 
> As the original author, can you say something about the intended use of this 
> feature ?

It was meant for a pretty narrow use of array types. If I knew how much work it 
would be to implement I probably would have not done it. :P I personally wanted 
it for static array lists that had methods like Add/Delete.
 
Here's an example of something I came across in a C++ project for decoding some 
data files old DOS games.

==

{$mode objfpc}

program Block;

type
  generic TBlock = record
bits: array[0..(Alpha + Depth) - 1] of T;
  end;

type
  TBlock32 = specialize TBlock;
  { ... other block types ... }

begin

end.

Here's an example from the bug tracker by another user (Akira) that helped with 
testing. More arrays you'll note.

==

program ConstMatrixExampleObjFPC;

{$mode ObjFPC}
{$modeswitch AdvancedRecords}

type
  String3 = String[3];

  generic TRawMatrix = array[0..N-1] of array[0..N-1] of 
T;

  generic TMatrix = record
  private type
ArrayType = specialize TRawMatrix;
  private
Data: ArrayType;
  public
class operator :=(constref Arr: ArrayType): TMatrix; inline;
procedure Display;
  end;

  class operator TMatrix.:=(constref Arr: ArrayType): TMatrix;
  begin
Result.Data := Arr;
  end;

  procedure TMatrix.Display;
  var I, J: SizeInt;
  begin
WriteLn('[');
for I := 0 to N - 1 do begin
  Write(' [');
  for J := 0 to N - 2 do
Write(Data[I, J], ', ');
  Write(Data[I, N - 1]);
  Writeln('] ');
end;
Write(']');
  end;

const RawMat: specialize TRawMatrix = (
  ('AAA', 'BBB', 'CCC', 'DDD'),
  ('EEE', 'FFF', 'GGG', 'HHH'),
  ('III', 'JJJ', 'KKK', 'LLL'),
  ('MMM', 'NNN', 'OOO', 'PPP')
);

var Mat: specialize TMatrix;

begin
  Mat := RawMat;
  Mat.Display();
end.

And another example from him that gets pretty clever. ;)

==

program Example;

// using Delphi-mode here as a matter of preference...

{$mode Delphi}

type
  Meters = record
  public const
ToKilometers = Value / 1000;
Unconverted = Value;
ToCentimeters = Value * 100;
ToMillimeters = Value * 1000;
ToFeet = Value * 3.28084;
  end;

  procedure Test;
  type
TenMeters = Meters<10>;
  const
KILOMETER_VALUE = TenMeters.ToKilometers;
UNCONVERTED_VALUE = TenMeters.Unconverted;
CENTIMETER_VALUE = TenMeters.ToCentimeters;
MILLIMETER_VALUE = TenMeters.ToMillimeters;
FOOT_VALUE = TenMeters.ToFeet;
  begin
WriteLn(KILOMETER_VALUE : 0 : 4);
WriteLn(UNCONVERTED_VALUE);
WriteLn(CENTIMETER_VALUE);
WriteLn(MILLIMETER_VALUE);
WriteLn(FOOT_VALUE : 0 : 4);
  end;

begin
  Test();
end.

Regards,
Ryan Joseph

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Anthony Walter via fpc-devel
Thank you Ryan and Sven. Your work is much appreciated as usual.

However, Michael beat me to it in asking how this feature is useful. I am
sure there might be use cases, but for right now I am coming up without any
real advantages. Could anyone with better insight than me please explain?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-26 Thread Michael Van Canneyt



On Sun, 26 Apr 2020, Ryan Joseph via fpc-devel wrote:





On Apr 26, 2020, at 5:13 AM, Sven Barth via fpc-devel 
 wrote:

The Free Pascal team is happy to announce the addition of a new language 
feature: constant parameters for generics.


Excellent! Thanks for getting this merged. It was a long battle but it's 
finally over. ;)


As the original author, can you say something about the intended use of this 
feature ?

Sven gave some examples, and they show how it works, but from his examples I 
don't see the point
of this feature.

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


Re: [fpc-devel] New feature announcement: constant parameters for generics

2020-04-25 Thread Ryan Joseph via fpc-devel


> On Apr 26, 2020, at 5:13 AM, Sven Barth via fpc-devel 
>  wrote:
> 
> The Free Pascal team is happy to announce the addition of a new language 
> feature: constant parameters for generics.

Excellent! Thanks for getting this merged. It was a long battle but it's 
finally over. ;) 

Regards,
Ryan Joseph

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


[fpc-devel] New feature announcement: constant parameters for generics

2020-04-25 Thread Sven Barth via fpc-devel
The Free Pascal team is happy to announce the addition of a new language 
feature: constant parameters for generics.


This allows to declare generic types or routines that aside from type 
parameters can also take constant parameters that can be used inside the 
generic as if one would use untyped constants. Together with inlining 
and optimizations this allows to generate optimal code that is yet flexible.


This feature was developed by Ryan Joseph. Thank you very much Ryan for 
your contribution and your patience until this feature was included.


A generic constant parameter is declared like this:

CONSTPARAM::=const : 
IDLIST::=[, ]
TYPE::=

The following types are supported for constant parameters:
- integer types (including range types)
- floating point types
- string types
- set types
- enum types
- Boolean types
- Pointer types

While the type declaration might look like a typed constant it is in 
fact an untyped constant. The type is used to allow the author of a 
generic to restrict the range of the type. This has some implications:


- the constant parameter can be used inside the generic whereever an 
untyped constant can be used (e.g. variable initializers, constant 
initializers, default parameters, array indices, compile time intrinsics 
and operations)
- types that can't be used for untyped constants can't be used for 
generic constant parameters either


Example:

=== code begin ===

{$mode objfpc}

type
  generic TStaticArray = array[0..N-1] of T;

generic function TimesX(aArg: Integer): Integer;
begin
  Result := aArg * N;
end;

var
  myArray: specialize TStaticArray;
  i: LongInt;
begin
  i := specialize TimesX<2>(21);
end.

=== code end ===

Important: Unlike C++ FPC does not support default specializations, thus 
doing recursive specializations together with operations on constants 
will result in out of stack exceptions or infinite loops:


=== code begin ===

{$mode objfpc}

type
  generic TTest = class
  const
    N1 = N - 1;
  type
    TSubTest = specialize TTest;
    // the following does not work currently for a different reason:
    // TSubTest = specialize TTest;
  end;

begin
end.

=== code end ===

Delphi compatibility: this feature is NOT Delphi compatible. However to 
not inconvience users that prefer mode Delphi this feature is also 
available in that mode as our stance usually is that Delphi code should 
compile with FPC while the inverse is not necessarily true.


Also this feature will NOT be part of 3.2.

Please give the generic constant parameters a try and report bugs in the 
bugtracker.


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