Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107171 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 74109 invoked from network); 16 Sep 2019 17:00:53 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by pb1.pair.com with SMTP; 16 Sep 2019 17:00:53 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id 452B32C0496 for ; Mon, 16 Sep 2019 07:37:48 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp3.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,HTML_MESSAGE, KHOP_HELO_FCRDNS,SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS16276 188.165.0.0/16 X-Spam-Virus: No Received: from poczta.brzuchalski.com (ns220893.ip-188-165-245.eu [188.165.245.118]) by php-smtp3.php.net (Postfix) with ESMTP for ; Mon, 16 Sep 2019 07:37:47 -0700 (PDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by poczta.brzuchalski.com (Postfix) with ESMTP id D07062984239 for ; Mon, 16 Sep 2019 16:37:15 +0200 (CEST) Received: from poczta.brzuchalski.com ([127.0.0.1]) by localhost (poczta.brzuchalski.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id edFXmtcbiGXE for ; Mon, 16 Sep 2019 16:37:13 +0200 (CEST) Received: from mail-oi1-f175.google.com (unknown [209.85.167.175]) by poczta.brzuchalski.com (Postfix) with ESMTPSA id 609692984233 for ; Mon, 16 Sep 2019 16:37:13 +0200 (CEST) Received: by mail-oi1-f175.google.com with SMTP id 7so8491022oip.5 for ; Mon, 16 Sep 2019 07:37:13 -0700 (PDT) X-Gm-Message-State: APjAAAVGSGKYF+ad5q4bb+FHjtPeEqyh5dxYYK2mEICB+8NUNronvQX8 4ZM7bhysLEjTOX6OfKeD40gcS3LTPCWSwkz9qfQ= X-Google-Smtp-Source: APXvYqwCR+uch4pj64EGu5lIG4U0bVW49oqHJuq+SEjF1k/TnUJXY4s74nVIGmzmaDp6fMp2dd+BNuHwIfRhRWJeiik= X-Received: by 2002:aca:5443:: with SMTP id i64mr57837oib.112.1568644632148; Mon, 16 Sep 2019 07:37:12 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Mon, 16 Sep 2019 16:37:00 +0200 X-Gmail-Original-Message-ID: Message-ID: To: Rowan Tommins Cc: PHP Internals List Content-Type: multipart/alternative; boundary="0000000000001403d40592ac8ac2" X-Envelope-From: Subject: Re: [PHP-DEV] Re: [RFC] Object Initializer From: michal@brzuchalski.com (=?UTF-8?Q?Micha=C5=82_Brzuchalski?=) --0000000000001403d40592ac8ac2 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Rowan, pon., 16 wrz 2019 o 15:47 Rowan Tommins napisa=C5=82(a): > On Mon, 16 Sep 2019 at 08:29, Micha=C5=82 Brzuchalski < > michal.brzuchalski@gmail.com> wrote: > > > Please keep in mind that initializing properties through object > initializer > > applies to visible properties and is possible to assign > > protected or private properties from the class scope as well. > > > > > The problem with that is that you need an extra static method to make use > of it, and you still need to get the arguments into that method. It might > be useful occasionally, but it still doesn't help constructors which are > setting a large number of private / protected properties. > > This RFC is not trying to help those constructors but tries to simplify instantiation objects and initializing properties there where any kind of constructor won't help, but rather would be unnecessary at all. The proposed solution applies well in DTO, "structs" etc. where you need to deal with 15+ properties which don't need any other validation than types and those are completely valid uses of public properties. > > > I don't see the reasons why many of you consider public properties a ba= d > > solution. PHP language has support for public properties > > and with typed properties, it is possible to ensure valid object state > > using VO's which are valid all the time, consider Uuid userland > > implementation > > no one checks if that's valid UUID, cause it's ensured by VO. > > > > > Firstly, it's not necessarily a case of "considering public properties a > bad solution"; it's about evaluating where the new feature could be used, > and where it wouldn't help. If there was a feature which helped this use > case *and* other use cases, I think that would be "better", but that > doesn't make this feature "bad". > > Secondly, typed properties certainly make public properties more appealin= g, > but there are still a bunch of things that you can't do with them, like > declaring them readonly, or having logic other than type validation in > getters and setters. Note that C#, which has object initializers, also ha= s > these features, making them a lot more powerful. > > True, C# which ships with object initializers also having property accessors, read-only etc. There are RFC's treating about named arguments, property accessors showing up occasionally on ML. But none of them was accepted. This is another feature and another talk. There is no RFC's which tries to solve all those issues in one big RFC, as such chances of success would be very low. > > > Any kind of features like promoting arguments from the constructor or > named > > arguments are fine but not efficient in those cases. > > Any good practices suggest limiting function|method arguments while the > > case is where there is a significant amount of properties > > to be initialized and additionally which don't need any kind of > validation > > due to VO, or simple scalars. > > > > > > That's a good point; named parameters make function calls scale much bett= er > to long lists of parameters, but *declaring* the constructor would still = be > unwieldy. The only way to improve that would be for the class to > effectively opt into having an initializer using a special syntax for the > constructor. Larry gave this example syntax: > > Please define long lists of parameters, cause issue this RFC is trying to solve is a simplification and ensuring properly initialized state of all required and visible properties and we talk here about DTO's like classes with tons of properties. You wouldn't want to put 15+ arguments in your constructor to initialize public properties which don't need other validation than proper type, right? Even if it would be just adding "public" keyword in front of them. > class Employee { > protected int $age; > protected string $name; > protected ?Employee $boss; > > public function hoist __construct() { > if ($age < 18) throw new ChildLaborException(); > } > } > > And Paul M Jones mentioned this version from Hack, where the parameters a= re > listed in the constructor, but don't need to be re-listed outside it: > > class Employee { > public function __construct( > protected int $age, > protected string $name, > protected ?Employee $boss > ) { > if ($age < 18) throw new ChildLaborException(); > } > } > > > Either of those, with named parameters, would be almost indistinguishable > from object initializers at the call site. Depending on the syntax chosen= , > it might be as similar as: > > // Call initializer, requires public properties > new Employee { age =3D> 42, name =3D> 'John Smith' }; > // Call constructor, requires special constructor definition > new Employee( age =3D> 42, name =3D> 'John Smith' ); > > Last RFC treating about named arguments has similar syntax with curly braces, but all together with previous ones tries to solve the issue through additional syntax inside parentheses, which means both features can coexist together. Calling instantiation always used parentheses as the way to pass constructor arguments let's keep it that way. Using object-initializer would use curly braces - just like it's used to be solved in other languages. > > That would require multiple new features, though, so initializers might b= e > more achievable in the short term, and perhaps there is room for both, > particularly if support for getters and setters improves. > > Here again, IIRC you're trying to solve the issue which is off-topic. Improving protected and private properties initialization through constructor is not the main target of current RFC. Thanks, Micha=C5=82 Brzuchalski --0000000000001403d40592ac8ac2--