Default record const values

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

Default record const values

Ryan Joseph
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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Default record const values

Free Pascal - General mailing list
Am Sa., 10. Nov. 2018, 10:06 hat Ryan Joseph <[hidden email]> geschrieben:
Should’t this work? This would be a good way to set default record values but it doesn’t seem to be supported.

TMyRecord is not yet completely parsed. There could be another field located behind the "default" constant. Thus using the type of the record aside from Pointers and method parameters and result is not allowed. 

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: Default record const values

Ryan Joseph
Not quite understanding how that’s not entirely parsed by the time you assign outside of the record. Even so I would expect it to copy what the const was able to capture, fully parsed or not.

Also, why does it work to do

begin
  r := TMyRecord.default;

in the main block?

> On Nov 10, 2018, at 4:55 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> TMyRecord is not yet completely parsed. There could be another field located behind the "default" constant. Thus using the type of the record aside from Pointers and method parameters and result is not allowed.
>

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: Default record const values

Ryan Joseph
In reply to this post by Free Pascal - General mailing list
This also fails.

type
        TMyRecord = record
                public
                        a: integer;
                        b: string;
        end;
const
        TMyRecord_Default: TMyRecord = (a: 100; b: 'foo');

var
        r: TMyRecord = TMyRecord_Default;


> On Nov 10, 2018, at 4:55 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> TMyRecord is not yet completely parsed. There could be another field located behind the "default" constant. Thus using the type of the record aside from Pointers and method parameters and result is not allowed.
>

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: Default record const values

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am Sa., 10. Nov. 2018, 12:44 hat Ryan Joseph <[hidden email]> geschrieben:
Not quite understanding how that’s not entirely parsed by the time you assign outside of the record. Even so I would expect it to copy what the const was able to capture, fully parsed or not.

It's not entirely parsed by the time the constant is declared. That is simply illegal code. 


Also, why does it work to do

begin
  r := TMyRecord.default;

in the main block?

It's not possible to use typed constants as initializers for variables.

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: Default record const values

Ben Grasset
In reply to this post by Ryan Joseph
On Sat, Nov 10, 2018 at 4:06 AM Ryan Joseph <[hidden email]> wrote:
Should’t this work? This would be a good way to set default record values but it doesn’t seem to be supported.

Personally I think the answer here is keep working on your new/alternate implementation of default field functionality! It's a missing puzzle piece for FPC generics in many ways.

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

Re: Default record const values

Ryan Joseph


> On Nov 11, 2018, at 6:51 AM, Ben Grasset <[hidden email]> wrote:
>
> Personally I think the answer here is keep working on your new/alternate implementation of default field functionality! It's a missing puzzle piece for FPC generics in many ways.
>

Not sure how default fields in generics help here. I just thought it would be nice if FPC supported this so we can init records at compile time easier. I’d prefer default struct fields like C++ has but typed const defaults would be an improvement.

I looked at the sources and in ttypedconstbuilder.read_typed_const_data (I think) it simply doesn’t support default record values with typed consts, only the = (a:x;b:x) style syntax. The typed const in the class was clearly defined as a hidden static var but I couldn’t figure out how to assign the values. Maybe I’ll look into it later.

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: Default record const values

Ben Grasset
On Sat, Nov 10, 2018 at 9:03 PM Ryan Joseph <[hidden email]> wrote:
Not sure how default fields in generics help here. I just thought it would be nice if FPC supported this so we can init records at compile time easier. I’d prefer default struct fields like C++ has but typed const defaults would be an improvement.

I guess I just meant that the other work you did recently seems (to me) to be in roughly the same "category" of functionality, and that it was also proof that there's not a whole lot of distance to close as far as the actual code required to implement it in FPC with regards to that kind of thing.

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

Re: Default record const values

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am 10.11.2018 um 09:35 schrieb Ryan Joseph:

> 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;
The compiler now correctly rejects such declarations with a "Type is not
completely defined error".

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: Default record const values

Ryan Joseph


> On Nov 12, 2018, at 5:06 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> The compiler now correctly rejects such declarations with a "Type is not completely defined error".

But this syntax worked if you assigned it within blocks. Why does it need to be removed? Since I discovered it I was planning on using it instead of class functions with default values which require an implementation and are much longer to write.



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: Default record const values

Ryan Joseph


> On Nov 12, 2018, at 8:08 AM, Ryan Joseph <[hidden email]> wrote:
>
> But this syntax worked if you assigned it within blocks. Why does it need to be removed? Since I discovered it I was planning on using it instead of class functions with default values which require an implementation and are much longer to write.

Here’s an example of what I was doing before. A constant is so much better and doesn’t require the implementation and we still get the same . syntax, i.e., TPoint.Up.

Instead of removing it maybe give the error unless it’s the last field of the record and in which case can assumed to be fully defined.

type
  TPoint = record
    x: TFloat;
    y: TFloat;
    class function Up (_x: TFloat = 0; _y: TFloat = -1): TPoint; static; inline;

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: Default record const values

Free Pascal - General mailing list
Am Mo., 12. Nov. 2018, 02:56 hat Ryan Joseph <[hidden email]> geschrieben:


> On Nov 12, 2018, at 8:08 AM, Ryan Joseph <[hidden email]> wrote:
>
> But this syntax worked if you assigned it within blocks. Why does it need to be removed? Since I discovered it I was planning on using it instead of class functions with default values which require an implementation and are much longer to write.

Here’s an example of what I was doing before. A constant is so much better and doesn’t require the implementation and we still get the same . syntax, i.e., TPoint.Up.

Instead of removing it maybe give the error unless it’s the last field of the record and in which case can assumed to be fully defined.

No, that is too random for a language.
This change is not up for discussion as it could lead to incorrect code. 

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: Default record const values

Martok
In reply to this post by Ryan Joseph
Am 10.11.2018 um 12:17 schrieb Ryan Joseph:
> This also fails.
I personally find this case much more limiting.

Another implication is that you can't build up consts from other record consts,
such as:

------------------------------
type
        TMyRecord = record
                        a: integer;
                        b: string;
        end;
const
        TMyRecord_Default: TMyRecord = (a: 100; b: 'foo');
        TMyRecord_Another: TMyRecord = (a: 200; b: 'bar');

        SomeRecords: array[0..1] of TMyRecord = (
          TMyRecord_Default,
          TMyRecord_Another);
------------------------------
There is a pointer hack to get around that, but it would be really useful if
this worked out of the box.

And yes, I know this is because record consts are (writeable, at worst) typed
consts and as such are only preinitialized global variables, not true consts,
but it still bothers me...

--
Regards,
Martok


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

Re: Default record const values

John Doe
In reply to this post by Free Pascal - General mailing list
On Mon, Nov 12, 2018 at 1:51 AM Sven Barth via fpc-pascal <[hidden email]> wrote:
The compiler now correctly rejects such declarations with a "Type is not completely defined error".

Making this not work is a ridiculous removal of a feature for no logical reason that serves no benefit to anyone whatsoever. It just makes records less useful, and that's it.

I've already encountered several large libraries that are pretty massively broken by this pointless change. You're very visibly just making up arbitrary "rules" out of nowhere that certainly aren't actually defined anywhere and implementing (or de-implementing) whatever strikes your fancy on a given day.

Also:

On Sat, Nov 10, 2018 at 4:56 AM Sven Barth via fpc-pascal <[hidden email]> wrote:
It's not possible to use typed constants as initializers for variables.

What are you talking about? Of course that's possible. People do it literally all the time. 

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

Re: Default record const values

Free Pascal - General mailing list
Am 14.11.2018 um 02:05 schrieb John Doe:
On Mon, Nov 12, 2018 at 1:51 AM Sven Barth via fpc-pascal <[hidden email]> wrote:
The compiler now correctly rejects such declarations with a "Type is not completely defined error".

Making this not work is a ridiculous removal of a feature for no logical reason that serves no benefit to anyone whatsoever. It just makes records less useful, and that's it.

Just to avoid any confusion: I am talking about a typed constant declared inside a record's declaration of the same type as the record. Constants outside a record, even inside other records work as before.
Also there can't be that many libraries affected, because this only ever worked in trunk. In 3.0.x the compiler simply crashed when encountering such a constant.


I've already encountered several large libraries that are pretty massively broken by this pointless change. You're very visibly just making up arbitrary "rules" out of nowhere that certainly aren't actually defined anywhere and implementing (or de-implementing) whatever strikes your fancy on a given day.

Also:

On Sat, Nov 10, 2018 at 4:56 AM Sven Barth via fpc-pascal <[hidden email]> wrote:
It's not possible to use typed constants as initializers for variables.

What are you talking about? Of course that's possible. People do it literally all the time.

=== code begin ===

type
  TTest = record
  public
    a: LongInt;
    b: LongInt;
  public //const
    //Default: array of TTest;// = (a: 42; b: 21);
  end;

const
  Test: TTest = (a: 42; b: 21);

var
  TestVar: TTest = Test; // <<<< this fails, because typed constants can't be used as initializers (would also be the case if Test and TestVar had any other type; only untyped constants are supported here)

=== code end ===

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: Default record const values

Benjamin Jan Alexander Rosseaux-2
In reply to this post by Ryan Joseph
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 <[hidden email]> 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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

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

Re: Default record const values

Free Pascal - General mailing list
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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Default record const values

Benjamin Jan Alexander Rosseaux-2
I'm using this solution myself for the vector and matrix data types at


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 <[hidden email]> 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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

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

Re: Default record const values

Ryan Joseph
In reply to this post by Benjamin Jan Alexander Rosseaux-2


> On Nov 29, 2018, at 2:27 AM, Benjamin Rosseaux <[hidden email]> 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  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal