Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109292 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 91309 invoked from network); 25 Mar 2020 16:00:08 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 Mar 2020 16:00:08 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 34A651804C5 for ; Wed, 25 Mar 2020 07:24:49 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS11403 66.111.4.0/24 X-Spam-Virus: No X-Envelope-From: Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 25 Mar 2020 07:24:48 -0700 (PDT) Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id 778B35C02CA for ; Wed, 25 Mar 2020 10:24:47 -0400 (EDT) Received: from imap26 ([10.202.2.76]) by compute7.internal (MEProxy); Wed, 25 Mar 2020 10:24:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; bh=RtWYk5Nq8hTwiJNaY7mV2P4AKWhnentLbuBD4Bc+C Og=; b=xITMQN2ifgvOfmqPoCSFts6eRHOsJcPnrym+tVUY01FeqtEzvD/y7kBsa YR9vAYtKBgVs7+uM7DWim+6trN3O3hE+n9FuITA02iBEZz4mWw1eW0/onMy9iAJQ ZYvkJJsyjHGtcJBiClQuFAnCFD5PaRaGXtGQIsXSQ4C5xTX8nZxFJYUAwdAdzt/Q /XZhPtniHoKwdWwckS9SVaL7JF/3HesVOqapYQejQGpLaNLabWlpfRHSKot5CUNp y/Zh0VhsdeR7tiDdmgxu6f0Xet7tnu3wlK/kToHLzh6W4BBo9zkU5NUn19q8fMry fzLZlB+m7RoJazqrWeb6TLLxBKuug== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedugedrudehgedgfeelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgfgsehtqhertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuffhomhgrihhnpehhihhvvgdrsghlohhgnecuvehluhhsthgvrhfuihiivgep tdenucfrrghrrghmpehmrghilhhfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtg hhrdgtohhm X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 03AE414200A2; Wed, 25 Mar 2020 10:24:47 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.1.7-1021-g152deaf-fmstable-20200319v1 Mime-Version: 1.0 Message-ID: <56f4f7bf-6086-4e10-addb-aba93ba23c5e@www.fastmail.com> In-Reply-To: References: <1b781e1e-3f27-485b-ab47-5eeaf9496548@www.fastmail.com> Date: Wed, 25 Mar 2020 09:24:25 -0500 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Improving PHP's Object Egonomics: A broad analysis From: larry@garfieldtech.com ("Larry Garfield") On Wed, Mar 25, 2020, at 5:57 AM, Nicolas Grekas wrote: > > > https://hive.blog/php/@crell/improving-php-s-object-ergonomics > > Named parameters are a pretty tough topic. I think one of the main p= oints > > of contention is that they make the parameters names part of the API= > > contract, and as such also subject to LSP. Your proposal offers two > > possible ways to side-step this: First, by making named parameters o= pt-in > > with a special syntax {}. Second, by limiting them to constructors. = The > > latter variant still exposes parameter names in the API, but at leas= t does > > not require their preservation across inheritance, as constructors a= re > > excluded from LSP. I'm somewhat torn on this, because it makes named= > > parameters unusable with the very large body of existing methods, an= d > > introduces an inconsistency in which methods can use named params an= d which > > don't. > > >=20 > I'd like to propose something on the topic. > I'm adding object literals to the mix because that's another feature o= f the > language that we're missing a lot IMHO. > Actually, there is one existing syntax for objects: (object) [...] >=20 > My proposal is to allow any class in the casting operator: (Foo) [...]= > By default, all keys of the casted array would map to properties (with= an > error when no matching property exists in the current visibility scope= ). We > would then allow for a new constructor method, either: > public function __create(array $values) > or: > public static function __create(array $values): static >=20 > This method would take over the cast operator and decide how to constr= uct > an instance of such a class. >=20 > There is one drawback: accepted keys are not documented. Sure, propert= y > declarations can give a big hint. >=20 > But I think we can solve this issue later: it's not a blocker to still= make > things work nicely. Also, this issue already exists with all methods t= hat > accept an array of options - and we'll find a solution for those - eit= her > using docblocks (there are already ways to use them for that) or using= > attributes (would be the best of course, once we have them.) >=20 > Note that this __create() method looks a lot like __unserialize(): it'= s > just called at a different place, but the implementations could be > essentially the same. Interesting. If that allowed populating private properties than that wo= uld be more capable than either of the initializer proposals that have b= een put forward. However, this alternate deserialization (as you note, it's basically __u= nserialize by another name) brings up other issues: 1) If it's a large number of properties, the __create method would still= need to manually assign them to properties, just like constructors now.= It wouldn't benefit from constructor promotion. 2) What's its order of execution with the constructor? Vis, does the co= nstructor run after __create or before? Does __construct get any parame= ters passed to it? If it doesn't get called, that's yet another way to = bypass the constructor and therefore bypass object validation. ("Make i= nvalid states unrepresentable". If the properties don't logically make = sense with each other that should be rejected as early as possible; synt= actically if we can, via early validation if not.) Named parameters have neither of those issues, as data still only comes = in via the constructor so both promotion and validation work fine. > Regarding the remainder, I think that all of readonly properties, > > asymmetric visibility and property accessors have their place and va= lue, > > with some overlap between them. As you already mentioned, the previo= us > > property accessors proposal also included asymettric visibility as a= > > special case, and that's how I would introduce it as well. > > >=20 > M=C3=A1t=C3=A9 suggested this syntax and it has my preference over the= one you menton > Larry: doubling the visibility keyword could be enough to express > read+write access: >=20 > public private $property; <=3D public read access, private write acces= s In that syntax, you have to remember which one comes first. There's no = indication for the casual reader why=20 public private $property; and=20 private public $property; are different. Plus, just looking at it, "wait, it's public and private= ? WTF? That doesn't even make sense." It also doesn't extend gracefully to property accessors. Whatever acces= sors do, if they ever get resolved, would conflict with that, and thus w= e'd have that many more weird combinations of property metadata that are= incompatible. The whole point of the syntax I proposed for asymmetric visibility is th= at it's gracefully extensible, even if a little more verbose. (If we ca= n find a syntax that is less verbose while still gracefully extensible, = I am on board with that.) --Larry Garfield