Discussion:
[fpc-pascal] Uniform initialization?
Ryan Joseph
2018-11-11 11:59:22 UTC
Permalink
Since I’ve got a little more free time I wanted to see if there was a simple solution to issue in Pascal that causes quite a bit of friction for me, i.e. constructor boiler plate. In c++ there is “uniform initialization” for structs which uses the {} syntax. It’s basically identically to record consts in Pascal, i.e.

type
tvec2 = record
x,y:integer;
end;

var
vec: tvec2 = (x:1;y1);

but it can be used at runtime (unlike Pascal which is compile time only). Many months ago I mentioned this and got a little positive response so I’d to ask again since I could probably implement it now.

Are any of these ideas appealing?

1) Simply move the typed const syntax down into blocks and use the type name like a function i.e.,

var
vec:tvec2;
begin
vec := tvec2(x:1;y1);

2) providing advanced records are on and perhaps a mode switch or some other kind of decorator, auto generate an implicit constructor, given no other constructors named “create" in the structure exist. i.e.,

{$something+}
type
tvec2 = record
x,y:integer;
end;
{$something-}

var
vec:tvec2;
begin
vec := tvec2.create(1,1); // tvec2 has no constructor defined so “create” with all public member fields as parameters is implicitly defined
vec := tvec2.create; // “create” is a static class function with default values so we can do this
end.

Here is the proposed implicit constructor for tvec2:

class function create(_x:integer=default(integer);y:integer=default(integer)):tvec2;static;

I prefer #2 because it’s easiest to type and looks most natural to Pascal. Not sure what the downsides are even???

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepa
t***@gmail.com
2018-11-11 15:03:59 UTC
Permalink
Hello,

Delphi 10.3 is going to support inline variable declarations like this:
begin
var i : Integer := 22;
WriteLn(i);
end;

I would assume it can also be used with records. For details, please see
http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html

So maybe that's the route to go.

Cheers,
Tobias


_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepas
Ryan Joseph
2018-11-11 15:16:42 UTC
Permalink
> On Nov 11, 2018, at 10:03 PM, ***@gmail.com wrote:
>
> Hello,
>
> Delphi 10.3 is going to support inline variable declarations like this:
> begin
> var i : Integer := 22;
> WriteLn(i);
> end;
>
> I would assume it can also be used with records. For details, please see
> http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html
>
> So maybe that's the route to go.

That’s interesting Delphi is breaking with the one of the oldest Pascal traditions. I have no idea what implications that would have for FPC or if it will be supported. If I recall this idea was shunned pretty thoroughly on the list a few months ago.

It’s still not a replacement for implicit constructors though since it’s tied to declaration time. Swift has implicit constructors for structs but uses the normal constructor syntax, unlike c++ which uses a special {} syntax. It really cuts down on boiler plate stuff when making new records. It’s a no-brainer for me and super easy to implement (already got most of it done today before I thought to ask) but lets see what people have to say.

Anonymous functions are still my biggest wish for FPC but they are considerably more complicated than what I can do currently.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pas
Sven Barth via fpc-pascal
2018-11-11 17:21:50 UTC
Permalink
Am 11.11.2018 um 16:03 schrieb ***@gmail.com:
> Hello,
>
> Delphi 10.3 is going to support inline variable declarations like this:
> begin
> var i : Integer := 22;
> WriteLn(i);
> end;
>
> I would assume it can also be used with records. For details, please see
> http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html
>
> So maybe that's the route to go.
We've already decided internally that we are *not* going to support this.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailm
Vojtěch Čihák
2018-11-11 22:45:01 UTC
Permalink
Very good.
 
V.
______________________________________________________________
> Od: "Sven Barth via fpc-pascal" <fpc-***@lists.freepascal.org>
> Komu: fpc-***@lists.freepascal.org
> Datum: 11.11.2018 18:22
> Předmět: Re: [fpc-pascal] Uniform initialization?
>
Am 11.11.2018 um 16:03 schrieb ***@gmail.com:
> Hello,
>
> Delphi 10.3 is going to support inline variable declarations like this:
> begin
>    var i : Integer := 22;
>    WriteLn(i);
>    end;
>
> I would assume it can also be used with records. For details, please see
> http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html <http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html>
>
> So maybe that's the route to go.
We've already decided internally that we are *not* going to support this.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal <http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal>
Ryan Joseph
2018-11-13 05:33:58 UTC
Permalink
> On Nov 12, 2018, at 5:45 AM, Vojtěch Čihák <***@atlas.cz> wrote:
>
> We've already decided internally that we are *not* going to support this.

Why does FPC have Delphi mode anyways? It’s not actually compatible with Delphi so what is it used for? It seems like if you’re a Delphi user you would just use the Delphi compiler.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/m
Sven Barth via fpc-pascal
2018-11-13 06:50:21 UTC
Permalink
Am Di., 13. Nov. 2018, 07:04 hat Ryan Joseph <***@thealchemistguild.com>
geschrieben:

>
>
> > On Nov 12, 2018, at 5:45 AM, Vojtěch Čihák <***@atlas.cz>
> wrote:
> >
> > We've already decided internally that we are *not* going to support this.
>
> Why does FPC have Delphi mode anyways? It’s not actually compatible with
> Delphi so what is it used for? It seems like if you’re a Delphi user you
> would just use the Delphi compiler.
>

The idea of the mode was to support Delphi code as much as possible, yes,
but in the past years the Delphi language has turned more and more into a
butchering of the Object Pascal language, a butchering that we don't want
to continue to support.
If it means missing out on some users that might have chosen FPC then so be
it. There are enough people that either start with FPC without any Delphi
background or that move over from an older version of which we do support
the features.

Regards,
Sven

>
Martin Wynne
2018-11-13 10:10:38 UTC
Permalink
Delphi mode is very useful.

It means old code from earlier versions of Delphi (in my case Delphi5)
can be open-sourced and made available via Lazarus to anyone interested,
without their needing to get an expensive copy of the latest Delphi.

Martin.
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailma
Vojtěch Čihák
2018-11-13 13:00:15 UTC
Permalink
IMO 100% Delphi compatibility was important some 10 years back when Kylix was discontinued and peope wanted to port their old Delphi projects to Linux. From that time boh FPC and Lazarus are mature enough and everyone who started a new project after - let's say - 2008 had to do the decision: Delphi or FPC+Laz.
 
V.
______________________________________________________________
> Od: "Martin Wynne" <***@templot.com>
> Komu: fpc-***@lists.freepascal.org
> Datum: 13.11.2018 11:11
> Předmět: Re: [fpc-pascal] Uniform initialization?
>
Delphi mode is very useful.

It means old code from earlier versions of Delphi (in my case Delphi5)
can be open-sourced and made available via Lazarus to anyone interested,
without their needing to get an expensive copy of the latest Delphi.

Martin.
_______________________________________________
fpc-pascal maillist  -  fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal <http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal>
Sven Barth via fpc-pascal
2018-11-11 17:25:57 UTC
Permalink
Am 11.11.2018 um 12:59 schrieb Ryan Joseph:
> Since I’ve got a little more free time I wanted to see if there was a simple solution to issue in Pascal that causes quite a bit of friction for me, i.e. constructor boiler plate. In c++ there is “uniform initialization” for structs which uses the {} syntax. It’s basically identically to record consts in Pascal, i.e.
>
> type
> tvec2 = record
> x,y:integer;
> end;
>
> var
> vec: tvec2 = (x:1;y1);
>
> but it can be used at runtime (unlike Pascal which is compile time only). Many months ago I mentioned this and got a little positive response so I’d to ask again since I could probably implement it now.
>
> Are any of these ideas appealing?
>
> 1) Simply move the typed const syntax down into blocks and use the type name like a function i.e.,
>
> var
> vec:tvec2;
> begin
> vec := tvec2(x:1;y1);
>
> 2) providing advanced records are on and perhaps a mode switch or some other kind of decorator, auto generate an implicit constructor, given no other constructors named “create" in the structure exist. i.e.,
>
> {$something+}
> type
> tvec2 = record
> x,y:integer;
> end;
> {$something-}
>
> var
> vec:tvec2;
> begin
> vec := tvec2.create(1,1); // tvec2 has no constructor defined so “create” with all public member fields as parameters is implicitly defined
> vec := tvec2.create; // “create” is a static class function with default values so we can do this
> end.
>
> Here is the proposed implicit constructor for tvec2:
>
> class function create(_x:integer=default(integer);y:integer=default(integer)):tvec2;static;
>
> I prefer #2 because it’s easiest to type and looks most natural to Pascal. Not sure what the downsides are even???
I'm not convinced that this feature is really needed, because one can
simply create a constant and assign that, would transport a clear name
as well.
But *if* I had to decide I would pick #1, cause then there wouldn't be
the chance to break existing code if a user decides to add a constructor
to their record and some other code relies on there not being a
constructor. Also due to the syntax
TYPENAME(FIELDNAME:VALUE[;FIELDNAME:VALUE[;…]]) it's in principle
possible to have the parser distinguish whether it's a typecast or a
default constructor.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.
leledumbo via fpc-pascal
2018-11-11 18:29:50 UTC
Permalink
> But *if* I had to decide I would pick #1, cause then there wouldn't be
> the chance to break existing code if a user decides to add a constructor
> to their record and some other code relies on there not being a
> constructor. Also due to the syntax
> TYPENAME(FIELDNAME:VALUE[;FIELDNAME:VALUE[;…]]) it's in principle
> possible to have the parser distinguish whether it's a typecast or a
> default constructor.

I would pick #1, too, seems more natural to me. There's no ambiguity as well
thanks to : in the syntax. I do wonder how often this would be used, though.
Despite being idiomatic in many languages, it doesn't really save much
typing that traditional way (if that's the main purpose).



--
Sent from: http://free-pascal-general.1045716.n5.nabble.com/
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bi
Sven Barth via fpc-pascal
2018-11-11 21:15:05 UTC
Permalink
Am 11.11.2018 um 19:29 schrieb leledumbo via fpc-pascal:
>> But *if* I had to decide I would pick #1, cause then there wouldn't be
>> the chance to break existing code if a user decides to add a constructor
>> to their record and some other code relies on there not being a
>> constructor. Also due to the syntax
>> TYPENAME(FIELDNAME:VALUE[;FIELDNAME:VALUE[;…]]) it's in principle
>> possible to have the parser distinguish whether it's a typecast or a
>> default constructor.
> I would pick #1, too, seems more natural to me. There's no ambiguity as well
> thanks to : in the syntax. I do wonder how often this would be used, though.
> Despite being idiomatic in many languages, it doesn't really save much
> typing that traditional way (if that's the main purpose).
Especially if you're using the same initialization values more often
you'd safe more time by declaring a suitable constant and using that as
the IDE can help you with code completion when using the constant.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mail
Ryan Joseph
2018-11-12 02:11:44 UTC
Permalink
> On Nov 12, 2018, at 12:25 AM, Sven Barth via fpc-pascal <fpc-***@lists.freepascal.org> wrote:
>
> I'm not convinced that this feature is really needed, because one can simply create a constant and assign that, would transport a clear name as well.

This is for runtime though and necessarily for constants. It’s just a short hand for initializing records so you don’t need to make boiler plate constructors. Often time when you create a new record you add a constructor so you can init in one line. Swift and c++ both have this default constructor and it’s a nice time saver.

for example:

struct Vec2 {
float x,y;
};

int main() {
Vec2 v = {1,2};
v = {v.x + 1, v.y + 1};
return 0;
}

> But *if* I had to decide I would pick #1, cause then there wouldn't be the chance to break existing code if a user decides to add a constructor to their record and some other code relies on there not being a constructor. Also due to the syntax TYPENAME(FIELDNAME:VALUE[;FIELDNAME:VALUE[;…]]) it's in principle possible to have the parser distinguish whether it's a typecast or a default constructor.

Yeah there could be name conflicts then. Maybe there should be some way to explicitly state you want the constructor with a certain name, i.e.,

type
TVec2 = record
x, y: integer;
constructor create; default;
end;

??? I don’t know, just an idea.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/li
Sven Barth via fpc-pascal
2018-11-12 06:55:29 UTC
Permalink
Am Mo., 12. Nov. 2018, 03:12 hat Ryan Joseph <***@thealchemistguild.com>
geschrieben:

>
>
> > On Nov 12, 2018, at 12:25 AM, Sven Barth via fpc-pascal <
> fpc-***@lists.freepascal.org> wrote:
> >
> > I'm not convinced that this feature is really needed, because one can
> simply create a constant and assign that, would transport a clear name as
> well.
>
> This is for runtime though and necessarily for constants. It’s just a
> short hand for initializing records so you don’t need to make boiler plate
> constructors. Often time when you create a new record you add a constructor
> so you can init in one line. Swift and c++ both have this default
> constructor and it’s a nice time saver.
>
> for example:
>
> struct Vec2 {
> float x,y;
> };
>
> int main() {
> Vec2 v = {1,2};
> v = {v.x + 1, v.y + 1};
> return 0;
> }
>

The advantage of the typecast like syntax is that you can get compiler
errors if for whatever reason the order of the fields is changed as they
are all named.


> > But *if* I had to decide I would pick #1, cause then there wouldn't be
> the chance to break existing code if a user decides to add a constructor to
> their record and some other code relies on there not being a constructor.
> Also due to the syntax TYPENAME(FIELDNAME:VALUE[;FIELDNAME:VALUE[;
]]) it's
> in principle possible to have the parser distinguish whether it's a
> typecast or a default constructor.
>
> Yeah there could be name conflicts then. Maybe there should be some way to
> explicitly state you want the constructor with a certain name, i.e.,
>
> type
> TVec2 = record
> x, y: integer;
> constructor create; default;
> end;
>
> ??? I don’t know, just an idea.
>

That is a constructor that takes no arguments. How do you think that is
useful for a constructor that *does* take arguments? That is absolutely not
clear at all for the user.

Regards,
Sven

>
Ryan Joseph
2018-11-12 11:49:08 UTC
Permalink
> On Nov 12, 2018, at 1:55 PM, Sven Barth via fpc-pascal <fpc-***@lists.freepascal.org> wrote:
>
> That is a constructor that takes no arguments. How do you think that is useful for a constructor that *does* take arguments? That is absolutely not clear at all for the user.

I just meant as a label so you know the record has a default constructor associated with it and it’s named. You’re right about the fields changing place and breaking constructors.

Honestly if the syntax is the type cast I probably would just make a constructor anyways because it’s less typing in the end. What I was really after is a way to save time making boiler plate constructers for records that merely hook up params to fields.

It feels like this is in the sprite of what properties aimed to accomplished, i.e. making getting/setters easier to manage.

Given that is there any syntax based off properties you would accept? Otherwise probably best to let this one rest.

I managed to get the syntax parsed for the type cast but not sure how to build the nodes or if it should point to a hidden constructor (lots of overhead in that case). Maybe I’ll come back to that later.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
http://li
Continue reading on narkive:
Loading...