On Mon, Mar 23, 2020, at 2:47 PM, Michał Brzuchalski wrote:
> Hi Larry,

> > The value here is combining constructor promotion with named parameters.
> > Constructor promotion itself is useful for the class implementer, but
> > doesn't help the caller.  Named parameters helps the caller, but doesn't
> > really help the class implementer.  The combination of both of them
> > together gives us something similar to the object-initializer syntax as a
> > net result, but with many other benefits because it's not a one-off syntax.
> >
> > So with the two of them together, you get:
> >
> > class Point {
> >   public function __construct({public int $x, public int $y});
> > }
> >
> > Which then allows any of these construction mechanisms:
> >
> > $p1 = new Point(5, 7);
> > $p2 = new Point({x: 5, y: 7});
> > $p3 = new Point({y: 7, x: 5});
> >
> > All of which result in an object you can use the same way:
> >
> > print $p1->x . ', '.  $p1->y;
> >
> >
> I agree it looks a little bit awkward and differs from object-initializers
> known from other languages,
> but let's say it would work somehow for this example. Now make it not 2 but
> 10-15 properties
> with real types sometimes quite long so after 3-5 of them you should break
> the line,
> then add some default values.
> Like a real entity which with typed properties doesn't need setters and
> getters.
> 
> The example grows but even when breaking a line after each
> parameter/property still could be somehow readable.
> 
> Now as we deal with Entity add some annotations or let's go hype, try 
> with
> new Attributes v2
> proposed by Benjamin Eberlei
> https://wiki.php.net/rfc/attributes_v2#userland_use-casemigrating_doctrine_annotations_from_docblocks_to_attributes
> 3 for $id and for the rest at least one attribute per property.
> 
> class Product {
>     public function __construct({
>         <<ORM\Id>>
>         <<ORM\Column>>
>         <<ORM\GeneratedValue>>
>         public int $id,
> 
>         <<ORM\Column(["unique" => true])>>
>         public string $name,
> 
>         <<ORM\Column>>
>         public string $description
>     });
> }
> 
> Let's stop on 3 I think it's enough to see it's:
> 1. unusual to see annotations in method signature declaration
> 2. not readable anymore.
> 
> Now if you say it shouldn't be like that and all the properties should be
> declared as normal properties,
> then the constructor is not needed to simplify the declaration but still
> requires a lot of boilerplate on
> the caller side undoubtedly.
> 
> Do you still think object-initializer is pointless and useless and can be
> replaced with
> named arguments and constructor arguments promotion?
> 
> Cheers,
> Michał


Yes, I responded to the annotations point in my earlier reply.  I hadn't 
considered those, so we'll likely need to consider alternate syntaxes if we 
want both annotations and constructor promotion (which I do).  However, note 
that even the (admittedly fugly) Product example you have above, each property 
name is listed only once, not 4 times, making it still an improvement on the 
status quo as far as redundancy.

However, I still hold that constructor promotion and named parameters, taken 
together, are strictly superior to a one-off syntax for objects that only 
supports public properties, as they offer more capabilities and have less 
potential to be confused with future additions.  

Eg, object-initalizer syntax vs named parameters on a constructor; which to use 
when?  Why?  Why do both exist?  They really shouldn't.  Named params would be 
better than object-initalizers all on their own, regardless of whether 
constructor promotion is included, precisely because they offer more capability 
for the same syntactic addition.

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to