Constants in generics

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

Re: Constants in generics

Free Pascal - General mailing list
Am Do., 3. Jan. 2019, 14:24 hat Alexander Shishkin via fpc-pascal <[hidden email]> geschrieben:
03.01.2019 15:45, Mattias Gaertner via fpc-pascal пишет:
> On Thu, 3 Jan 2019 14:58:00 +0300
> Alexander Shishkin via fpc-pascal <[hidden email]>
> wrote:
>
>> [...]
>> This is OK (both T and U are integer):
>> generic TMyRecord1<const T, const U: integer> = record end;
>
> That is inconsistent to normal Pascal arguments.
>
> <accessors> Name[, Name ...][:type]
>
> Isn't it?
>

I personally do not like const prefix either. More consistent with other
constraints would be:

T and U integer const
generic TMyRecord1<T, U: integer> = record end;
generic TMyRecord1<T, U: const, integer> = record end;

Similar to
generic TMyRecord1<T, U: IUnknown> = record end;
generic TMyRecord1<T, U: class, IUnknown> = record end;

T and U any const
generic TMyRecord1<T, U: const> = record end;

Similar to
generic TMyRecord1<T, U: record> = record end;

And more complex example:

generic TMyRecord1<T, U: record; X, Y: const> = record end;

I'm against that. A constant parameter is a different beast from a type parameter so requiring a special prefix for them is legitimate. Also this is more like the normal routine parameter syntax, thus everyone will feel right at home. 

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: Constants in generics

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


> On Jan 3, 2019, at 6:20 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> Correct. ";" separates different parameter types, "," separates those of the same type. Though I agree with Mattias that "const T, const U" (with or without ": Integer") should not work (but then "T, const U" should also not work for consistency).
> Essentially it should behave like a routine's parameter clause.

I guess that makes sense that if a type parameter is followed by a const parameter then those are essentially different types and following the same logic should be separated with a semicolon.

That means the parser only knows if a ; is required after the const keyword is found. Does that matter?

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: Constants in generics

Free Pascal - General mailing list
Am Do., 3. Jan. 2019, 17:50 hat Ryan Joseph <[hidden email]> geschrieben:


> On Jan 3, 2019, at 6:20 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> Correct. ";" separates different parameter types, "," separates those of the same type. Though I agree with Mattias that "const T, const U" (with or without ": Integer") should not work (but then "T, const U" should also not work for consistency).
> Essentially it should behave like a routine's parameter clause.

I guess that makes sense that if a type parameter is followed by a const parameter then those are essentially different types and following the same logic should be separated with a semicolon.

That means the parser only knows if a ; is required after the const keyword is found. Does that matter?

The approach should be like this:
- const is allowed at the start of the parameters or after a ";" 
- a parameter name is either followed by a ",", ";", ":" or ">" (that should already be the case)
- a ":" is either followed by a type constraint (for non const parameters) or a type name that allows constants (for const parameters); in either case this is followed by a ";" or the closing ">" 

I think that should cover everything 🤔

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: Constants in generics

Ryan Joseph


> On Jan 3, 2019, at 11:33 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> The approach should be like this:
> - const is allowed at the start of the parameters or after a ";"
> - a parameter name is either followed by a ",", ";", ":" or ">" (that should already be the case)
> - a ":" is either followed by a type constraint (for non const parameters) or a type name that allows constants (for const parameters); in either case this is followed by a ";" or the closing ">"
>
> I think that should cover everything 🤔
>

Ok, I’ll try to change that later since it’s minor.

I read your old email about removing “tgenericparamdef”: quote from you: "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.”

You’re probably right that’s better design but that means I need to overhaul a rather fundamental element of how generics were designed and goes well outside the changes I made. At the core of the problem is tspecializationcontext.genericdeflist contains tdef’s and changing that to symbols means I need to rename lots of variables, move methods from tstoreddef and all the other various places where types were used. Sorry but there’s just not enough time for me to dive into that right now so that will have to wait.

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: Constants in generics

Free Pascal - General mailing list
Am 03.01.2019 um 23:14 schrieb Ryan Joseph:

>
>> On Jan 3, 2019, at 11:33 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>>
>> The approach should be like this:
>> - const is allowed at the start of the parameters or after a ";"
>> - a parameter name is either followed by a ",", ";", ":" or ">" (that should already be the case)
>> - a ":" is either followed by a type constraint (for non const parameters) or a type name that allows constants (for const parameters); in either case this is followed by a ";" or the closing ">"
>>
>> I think that should cover everything 🤔
>>
> Ok, I’ll try to change that later since it’s minor.
>
> I read your old email about removing “tgenericparamdef”: quote from you: "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.”
>
> You’re probably right that’s better design but that means I need to overhaul a rather fundamental element of how generics were designed and goes well outside the changes I made. At the core of the problem is tspecializationcontext.genericdeflist contains tdef’s and changing that to symbols means I need to rename lots of variables, move methods from tstoreddef and all the other various places where types were used. Sorry but there’s just not enough time for me to dive into that right now so that will have to wait.
Fair enough. In that case support for constants in generics will have to
wait as well. 🤷‍

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: Constants in generics

Ryan Joseph


> On Jan 3, 2019, at 11:11 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> Fair enough. In that case support for constants in generics will have to wait as well. 🤷‍

Who designed the generics btw? I’m not 100% certain that it’s even safe to change their design like this so it would be nice to hear from them. Inline specializations rely on tprocdef and if I change everything to work on symbols we could break generic procedure overloads.

One thing I can do to remove my dummy tgenericparamdef class is to keep a separate list of const syms in tspecializationcontext.

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: Constants in generics

wkitty42
On 1/4/19 1:47 PM, Ryan Joseph wrote:
>
>> On Jan 3, 2019, at 11:11 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>>
>> Fair enough. In that case support for constants in generics will have to wait as well. 🤷‍
>
> Who designed the generics btw?


unless i'm highly mistaken, you've been talking to them... they're quoted above,
even ;)


--
  NOTE: No off-list assistance is given without prior approval.
        *Please keep mailing list traffic on the list unless*
        *a signed and pre-paid contract is in effect with us.*
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
Am Fr., 4. Jan. 2019, 21:11 hat <[hidden email]> geschrieben:
On 1/4/19 1:47 PM, Ryan Joseph wrote:
>
>> On Jan 3, 2019, at 11:11 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>>
>> Fair enough. In that case support for constants in generics will have to wait as well. 🤷‍
>
> Who designed the generics btw?


unless i'm highly mistaken, you've been talking to them... they're quoted above,
even ;)

I didn't design the original implementation, but the improvements for the last five years or so have been mine. 😅

@Ryan: I can give it a try to rework the list from defs to syms and you can then put your const implementation on top of that. 

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: Constants in generics

wkitty42
On 1/5/19 3:18 AM, Sven Barth via fpc-pascal wrote:
> Am Fr., 4. Jan. 2019, 21:11 hat <[hidden email]> geschrieben:
>     On 1/4/19 1:47 PM, Ryan Joseph wrote:
>      > Who designed the generics btw?
>
>     unless i'm highly mistaken, you've been talking to them... they're quoted
>     above, even ;)
>
> I didn't design the original implementation, but the improvements for the last
> five years or so have been mine. 😅

i didn't pick up this list until 2011 Feb 08... i don't recall when i first read
anything about generics and FPC but it was a while after i had joined... your
voice was the only one responding to questions and producing the code...

> @Ryan: I can give it a try to rework the list from defs to syms and you can then
> put your const implementation on top of that.

that would be nice... const(ants?) have been asked for a lot in generics for FPC...


--
  NOTE: No off-list assistance is given without prior approval.
        *Please keep mailing list traffic on the list unless*
        *a signed and pre-paid contract is in effect with us.*
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

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


> On Jan 5, 2019, at 1:18 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> I didn't design the original implementation, but the improvements for the last five years or so have been mine. 😅
>
> @Ryan: I can give it a try to rework the list from defs to syms and you can then put your const implementation on top of that.
>

Last night I just went for it and pulled out the defs which was smoother than I thought. It seems to work out but I need to test more I think.

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: Constants in generics

Ryan Joseph
Given the new syntax requirements we talked about there needs to be a ; after T now. What error should be used if there isn’t a ; semicolon separator between types and consts? I just used a parser_e_illegal_expression for now.

generic TStuff<T,const A,B,C:integer> = record

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: Constants in generics

Jonas Maebe-3
On 05/01/19 18:51, Ryan Joseph wrote:
> Given the new syntax requirements we talked about there needs to be a ; after T now. What error should be used if there isn’t a ; semicolon separator between types and consts? I just used a parser_e_illegal_expression for now.

scan_f_syn_expected=02003_F_Syntax error, "$1" expected but "$2" found


Jonas

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

Re: Constants in generics

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am Sa., 5. Jan. 2019, 17:28 hat Ryan Joseph <[hidden email]> geschrieben:


> On Jan 5, 2019, at 1:18 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> I didn't design the original implementation, but the improvements for the last five years or so have been mine. 😅
>
> @Ryan: I can give it a try to rework the list from defs to syms and you can then put your const implementation on top of that.
>

Last night I just went for it and pulled out the defs which was smoother than I thought. It seems to work out but I need to test more I think.

Sometimes things *do* work out :D

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: Constants in generics

Ryan Joseph
In reply to this post by Jonas Maebe-3
Here’s the new syntax requirements for const params which require types and consts be separated by semicolons.

Does TStuff2 need a ; between the two const params? Sven said consts must follow ; or < but they’re both consts so I thought I’d ask to make sure.

type
        generic TStuff0<A:TObject;T> = record end;
        generic TStuff1<T;const A,B,C:integer> = record end;
        generic TStuff2<const A,const B,C:string> = record end;
        generic TStuff3<const A:integer;T> = record end;


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: Constants in generics

Free Pascal - General mailing list
Am Sa., 5. Jan. 2019, 22:57 hat Ryan Joseph <[hidden email]> geschrieben:
Here’s the new syntax requirements for const params which require types and consts be separated by semicolons.

Does TStuff2 need a ; between the two const params? Sven said consts must follow ; or < but they’re both consts so I thought I’d ask to make sure.

type
        generic TStuff0<A:TObject;T> = record end;
        generic TStuff1<T;const A,B,C:integer> = record end;
        generic TStuff2<const A,const B,C:string> = record end;
        generic TStuff3<const A:integer;T> = record end;

Just think about it logically: B and C can't be anything else than const, so why would we need to repeat it? 

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: Constants in generics

Ryan Joseph


> On Jan 6, 2019, at 1:28 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> Just think about it logically: B and C can't be anything else than const, so why would we need to repeat it?

I’m not saying anyone would actually write that generic but if it does appear what terminator is used? A more clear example is: <const A,const B>. It would make more sense to say <const A,B> of course but it could appear the other way. Maybe I’m not understand you though.

For now I just required all const lists separated with ; since that was your first suggestions, i.e. <const A;const B>

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: Constants in generics

Ryan Joseph
Last question I have I think.

Is this the best way to get "pretty name" string for a set? Having to loop through the entire range of the set is not so great but I don’t see another way. I feel like there should be some utility functions to get names for ord defs also but I just did a crude string conversion for now.

new(ps);
ps^:=tsetconstnode(node).value_set^;
sym:=cconstsym.create_ptr(undefinedname,constset,ps,fromdef);
setdef:=tsetdef(tsetconstnode(node).resultdef);
enumdef:=tenumdef(setdef.elementdef);
prettyname:='[';
for i := setdef.setbase to setdef.setmax do
  if i in tsetconstnode(node).value_set^ then
    begin
      enumsym:=enumdef.int2enumsym(i);
      if assigned(enumsym) then
        enumname:=enumsym.realname
      else if enumdef.typ=orddef then
        begin
          if torddef(enumdef).ordtype=uchar then
            enumname:=chr(i)
          else
            enumname:=tostr(i);
        end
      else
        enumname:=tostr(i);
      if length(prettyname) > 1 then
        prettyname:=prettyname+','+enumname
      else
        prettyname:=prettyname+enumname;
    end;
prettyname:=prettyname+']';


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: Constants in generics

Ben Grasset
Just wanted to say, I've been playing around with Ryan's github branch that contains this functionality and I'm loving it! It really opens up a ton of interesting possibilities in general, and also a lot of potential for optimization via constant folding for generic containers that wasn't really possible previously. Here's a more "advanced" example I threw together of the kinds of things you can actually do with this (I'm aware the final syntax for the declarations is going to be slightly different, not that it matters really):

program Example;

{$Mode ObjFPC}{$H+}{$J-}
{$ModeSwitch AdvancedRecords}
{$PointerMath On}

type
  generic TStaticList<T, const L: PtrUInt, const H: PtrUInt> = record
  public type
    TStaticListEnumerator = record
    public type PT = ^T;
    strict private
      FFirst, FLast, FCurrent: PT;
    public
      class function Create(var List: TStaticList): TStaticListEnumerator; inline; static;
      function MoveNext: Boolean; inline;
      property Current: PT read FCurrent;
    end;
  strict private
    Items: array[L..H] of T;
  public
    function Low: PtrUInt; inline;
    function High: PtrUInt; inline;
    procedure Initialize; inline;
    function GetEnumerator: TStaticListEnumerator; inline;
  end;

  class function TStaticList.TStaticListEnumerator.Create(var List: TStaticList): TStaticListEnumerator;
  begin
    with Result do begin
      FFirst := @List.Items[L];
      FLast := @List.Items[H];
      FCurrent := FFirst - 1;
    end;
  end;

  function TStaticList.TStaticListEnumerator.MoveNext: Boolean;
  begin
    Inc(FCurrent);
    Result := (FFirst <> FLast) and (FCurrent <= FLast);
  end;

  function TStaticList.Low: PtrUInt;
  begin
    Result := L;
  end;

  function TStaticList.High: PtrUInt;
  begin
    Result := H;
  end;

  procedure TStaticList.Initialize;
  var I: PtrUInt;
  begin
    for I := Low() to High() do Items[I] := T(I);
  end;

  function TStaticList.GetEnumerator: TStaticListEnumerator;
  begin
    Result := TStaticListEnumerator.Create(Self);
  end;

var
  AsciiList: specialize TStaticList<Char, 33, 126>;
  P: PChar;

begin
  AsciiList.Initialize();
  for P in AsciiList do Write(P^);
end.

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

Re: Constants in generics

Ryan Joseph


> On Jan 6, 2019, at 1:31 PM, Ben Grasset <[hidden email]> wrote:
>
>   generic TStaticList<T, const L: PtrUInt, const H: PtrUInt> = record
>

This is exactly the reason I added the feature, there’s no way to extend static arrays otherwise! Beyond this one thing I have no idea what to use them for. ;)

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: Constants in generics

Ben Grasset
On Sun, Jan 6, 2019 at 4:23 PM Ryan Joseph <[hidden email]> wrote:
This is exactly the reason I added the feature, there’s no way to extend static arrays otherwise! Beyond this one thing I have no idea what to use them for. ;)

I've got a bunch of stuff in mind actually that I'm waiting on the "final" version for before I start getting into too seriously. There's a lot that's possible as far as custom string types and such if you combine this with operator overloading.

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