Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107191 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 18202 invoked from network); 17 Sep 2019 15:26:07 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by pb1.pair.com with SMTP; 17 Sep 2019 15:26:07 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id 729822CFDDF for ; Tue, 17 Sep 2019 06:03:15 -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=-2.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS11403 64.147.123.0/24 X-Spam-Virus: No Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp3.php.net (Postfix) with ESMTPS for ; Tue, 17 Sep 2019 06:03:14 -0700 (PDT) Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id E19235B9 for ; Tue, 17 Sep 2019 09:03:13 -0400 (EDT) Received: from imap26 ([10.202.2.76]) by compute7.internal (MEProxy); Tue, 17 Sep 2019 09:03:14 -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=fm3; bh=UIF6JsvFBdq9J5OXGAZA8tdVufIhf00rYZpfQigd+ nI=; b=CLpAH567nphwoMQzlr6ZajuooxSkCaswlMtt9Mr7BQixF1V6UbBA52DY8 Uat/LGQc3FRjrct2Vd+bwVzwidMXgQPnDDuh3+TVJXBKTG1XGglCjCZ74oxs+f3I 1L+rcxU9Ct7+KrV8S3ReCwLb8wkluAGfuSOWBhxML1DYrH0zopWNIqX0gUTW/oSO n3DPYExp8ycVkvzCyYBSti22JSfKurqrYTm1M3KlbvyohulE3znxnIvvmLOCQa9w WtwWHiswaOrkvqnDgYfVmpEtvBe/Mlx5PMx/HXaSrInDfaSrfqTsFYwEKGPYq8QN rii48K2igCWb0fAOPijiuyKg2A2jQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrudeigdeffecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvufgtgfesthhqredtreerjeenucfhrhhomhepfdfnrghr rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh hmqeenucffohhmrghinhepfihikhhiphgvughirgdrohhrghenucfrrghrrghmpehmrghi lhhfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmnecuvehluhhsth gvrhfuihiivgeptd X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 388B414200A1; Tue, 17 Sep 2019 09:03:13 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.1.7-237-gf35468d-fmstable-20190912v1 Mime-Version: 1.0 Message-ID: In-Reply-To: References: <472D3E22-18D9-4C25-8961-C1DDEF482981@newclarity.net> <58673C6E-6632-42D9-BCBF-0294A62EB001@newclarity.net> <83819928-59BF-4C02-9F97-59306EE97F90@newclarity.net> <425cf402-370f-4d6f-9d9e-82a044b70c45@www.fastmail.com> Date: Tue, 17 Sep 2019 08:02:22 -0500 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Envelope-From: Subject: Re: [PHP-DEV] Features related to Object Initializers From: larry@garfieldtech.com ("Larry Garfield") On Mon, Sep 16, 2019, at 7:10 PM, Mike Schinkel wrote: > > On Sep 16, 2019, at 6:20 PM, Larry Garfield = wrote: > >=20 > > I think everyone's in agreement about: > >=20 > > 1) Making objects easier to work with. > > 2) Devs should use objects more. >=20 > I am glad we are reaching some common ground. :-) >=20 > > (Side note: I have an article submitted to php[architect] entitled "= Never* use arrays" that goes into this topic in much more detail. I am = 100% on board with getting developers using objects more and arrays less= .) >=20 > Yes, I saw the article on your blog that you linked. Very nice. :-) I have a presentation on the subject that I keep submitting to conferenc= es. I'm waiting for one to pick it up. :-) > > However, why do we want devs to use objects more? If we just want t= he arrow-like syntax, then this works today: > >=20 > > $val =3D (object)[ > > 'foo' =3D> 'bar', > > 'baz' =3D> 5, > > ]; > >=20 > > And now developers are using an anonymous "object". However, that o= ffers basically no meaningful improvement except funnier passing semanti= cs. > > ... >=20 > > 2) They're more self-documenting and statically analyzable (by your = IDE or any other tool)... but that's true only if you have an explicitly= defined class! > > ... > > So for me, the entire "easier to use anonymous one-off classes" argu= ment falls apart, because there's no material benefit there other than s= aying "but now it's using objects". For that, as noted, we already have= an ample syntax that accomplishes just as much. >=20 >=20 > I can envision several benefits you do not mention, maybe because=20 > you've forgotten them, were not aware of them, or they did not occur t= o=20 > you? >=20 > In descending order of significance: >=20 > 1. IDEs could validate local uses for stdClasses =E2=80=94 Given the f= ollowing=20 > syntax, PhpStorm could and likely would implement an inspection that=20= > displayed a warning on the line with $val->bazoom because everything i= t=20 > needs to validate is there. And I see no reason other IDEs could not=20= > do the same: >=20 > $val =3D stdClass{ > foo =3D> 'bar', > baz =3D> 5, > }; > echo $val->bazoom; Can they? In the super-narrow case of the object being defined in the s= ame scope as it's used, potentially. But once I pass it elsewhere, the = static analyzer will have a really hard time figuring out what it's supp= osed to be. Example: $val =3D stdClass{ foo =3D> 'bar', baz =3D> 5, }; echo $val->bazoom; // IDE can tell this is wrong. function thingie(object $params) {=20 echo $object->bazoom; } thingie($val); // we know this will break, but the IDE can't really tell= thingie(stdClass{bazoom: 5}); // This won't break. Granted, I have not written a static analyzer myself so it's possible I'= m speaking out of my butt here, but I don't see how an analyzer could re= asonably tell if the echo statement in the function was correct or not b= ecause it has no local information on which to base that decision absent= a defined class or interface. > 2. Empowering beginners =E2=80=94 If you are a beginner, or a work-to-= live[1]=20 > programmer then I think there is a good chance you will find the synta= x=20 > (object)[..] foreign and confusing. I think they would find the=20 > following syntax easier to tackle and thus more likely to use,=20 > especially if they came from Javascript (note I omitted stdClass in=20= > hopes we could land on using such syntax for stdClass or anonymous=20 > classes): >=20 > $val =3D { > foo =3D> 'bar', > baz =3D> 5, > }; >=20 > By empowering beginners they would be more likely to objects they can=20= > later refactor instead of arrays (see #5 below.) To clarify: I virtually never use (object)[] syntax myself. I think it'= s been a decade or more since I did so. I would not endorse such a thin= g. My point is that what's being proposed here, in relation to anon cla= sses, has no meaningful benefit over that. > 3. Simplifying refactoring =E2=80=94 It will be easier to refactor an = object=20 > initializer for stdClass to a declared class than to refactor from the= =20 > hybrid array/object syntax. Citation needed? And why not just define your data types in the first p= lace? > 4. Simplified syntax =E2=80=94 I tend to make a lot more typos when=20= > initializing array keys in PHP than I do when initializing objects in=20= > GoLang (the proposed PHP syntax is very similar to the equivalent in=20= > Go.) Maybe I am unique in that, but I doubt it. =20 You're definitely not unique because I do that too, and it's one of the = examples I call out in presentations on why defined classes are superior= to arrays. =20 I'd noticed the Go inspiration as well. I think it works well in Go, bu= t less so in PHP. Also bear in mind that in Go, you're instantiating an= explicitly defined structure; even if you're defining that structure in= line at instantiation, you're first defining the structure types. (And = the syntax for doing so inline is really funky.) So that's no help at a= ll for the anon class case. > I also find array keys with quotes harder to read (but maybe that's=20= > because I have 56 year old eyes instead of younger eyes that guys like= =20 > you have? :-) >=20 > 5. The (object)[...] syntax feels like a hack =E2=80=94 I use that syn= tax, but=20 > every time I do I feel like I am doing something I should not be. And= =20 > I also rarely see that syntax being used in the wild, so maybe others=20= > feel the same? It is a hack; again, I am in no way endorsing its usage. Just saying th= at an anon struct with arrows offers no meaningful advantages over the c= urrent hack. > 5. PSON! =E2=80=94 I we had an object initializer syntax, we could fin= ally have=20 > a competitor to JSON; i.e. PSON! Imagine if we had only had it 15=20 > years ago... :-o I don't really follow this one, especially as you're essentially describ= ing an inline JSON for PHP. :-) > Remember, the above were in descending order of significance. >=20 > > It's only an advantage if I do this: > >=20 > > function doSomething(int $a, SomethingOptions $options =3D null) { .= .. } > >=20 > > Doing that has many advantages, I think we all agree. But going hal= fway doesn't give us any benefits other than swapping [' '] for ->. >=20 > Other than the assertion that it only has advantages with declared=20 > classes, I do generally agree this is usually the most beneficial=20 > approach. >=20 > But as I said before, naming is hard =E2=80=94 except for abstract exa= mples=20 > where you can just name it "Something" :-) =E2=80=94 and developers of= ten don't=20 > know what object schema they will need until they have written much of= =20 > the code. So the ability to have a syntax that supports stepwise=20 > refinement rather than starting with one and having to switch to the=20= > other makes a lot more sense to me. =20 >=20 > Allowing developers to start with doSomething(int $a, object $options = =3D=20 > null) and then later refine the code to doSomething(int $a,=20 > SomethingOptions $options =3D null) creates less discontinuity for=20 > development rather than giving them only one option for anonymous clas= s=20 > initializer, e.g. the array initializer syntax? I think this is where we fundamentally disagree. "It's just like the an= onymous blob of array data you're used to but with arrows" is not a usef= ul or helpful stepping stone toward defined classes. If anything, I see= it as one less reason for people to start using real defined classes be= cause "it's already objects, so it's OO, so what do you want from my lif= e?" When I was a kid, there was a brief period where schools tried to teach = an "intermediate" writing style between print and cursive called D'Neali= an. The theory was that it would make it easier to transition them from= print to cursive. In practice, it did the exact opposite because it me= ant two, not one, transitions in writing style and a lot of students got= stuck at the intermediate and never moved on. Myself included; to this= day I write in a sort of perverted D'Nealian/curisve and never learned = proper cursive. cf: https://en.wikipedia.org/wiki/D%27Nealian The intermediate step you describe I see not actually helping matters, a= nd if anything hurting them. That's because good OOP is not "passing ar= rays but with defined properties". If someone replaced this: function doSomething(int $a, array $options =3D []) { ... } with this: function doSomething(int $a, SomethingOptions $options =3D null) { ... }= I would still reject their code, because it's just using an object as an= over-engineered way around... the lack of named parameters. Rather, th= e defined class should mean something, not just be a bunch of names coll= ected together. That's a different way of thinking, and trying to have = a smooth "lots of easy little steps" transition will just leave a lot of= people, and their code, stuck at all of those intermediate steps. > > So rather than making it easier for people to make "anonymous struct= s that use object syntax", we should be making it easier for people to d= efine for-realsies named classes and using them, because *that* is where= the benefit comes from. >=20 > If you can actually make it easy, I would be the first to support that= .=20 > I just cannot envision how you can without more upfront complexity tha= n=20 > simple object initializers need. =20 >=20 > So please, prove me wrong! :-) >=20 > > And for that part of the problem (making named struct-like classes e= asier to work with), as noted in the other thread I find the named param= eters/auto-promotion combination to solve the problem just as well, and = then some. >=20 > There has recently been a call from several people on the list for=20 > everyone to try and find solutions that are not "You loose so I can=20= > win." =20 >=20 > Rather than protest object initializers to enable named=20 > parameters/auto-promotion instead, can we not work together to find a=20= > way to achieve all three with one simple syntax and as few new sigils=20= > used as possible? As I said before, I think named params and constructor-promotion would d= o just that, or nearly so, depending on the particulars of their syntax.= (The devil is always in the details.) My engine-C-fu is basically nil (or null, since this is PHP), so I'm no = help in implementing such things, but I'm happy to collaborate on the re= search and design part of those, with an eye toward making the construct= ion process as easy as possible. --Larry Garfield