Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112129 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 19063 invoked from network); 27 Oct 2020 17:13:37 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 27 Oct 2020 17:13:37 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E7555180533 for ; Tue, 27 Oct 2020 09:32:18 -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,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from wout5-smtp.messagingengine.com (wout5-smtp.messagingengine.com [64.147.123.21]) (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 ; Tue, 27 Oct 2020 09:32:17 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id CB945153F for ; Tue, 27 Oct 2020 12:32:16 -0400 (EDT) Received: from imap26 ([10.202.2.76]) by compute4.internal (MEProxy); Tue, 27 Oct 2020 12:32:16 -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=fm1; bh=/bUy/IvDYgzHGIDYv7iDIAyt9sklm0GDsc3aoV6C6 HI=; b=H0DMn5u+Vitmd6fxuWqbzGgCm2dg7e3Hjyp6Rn9PQgr1Ifhod7ZOYxGan GAfwVPk10bs1SThYXCdnSgNiDYNBa6MbLhafyad9duVAOIbFVvLk+KysBjWDGMbQ M1D2arljiP3/O79EMgmi3Chc/tAYEyC9RW94Mw30LEhhDRQsRBZqRAQ6AhMbKRnz bP8oZQyH9Z3QMHXCKpoPULAXgT5OofNSZFm7BfF3YXWMm95QT39H0HT/krJDZ1A1 AMD/S+HNzzK3QqJmqhQTDAaWqyMzmWRbkmcV7Acdt8CM+0Q9HNJezJgHW5p0K+Hs 9hib4lHPOKMl+YSSEGyTTyK5qQT1w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrkeelgdeltdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenog fuuhhsphgvtghtffhomhgrihhnucdlgeelmdenucfjughrpefofgggkfgjfhffhffvufgt gfesthhqredtreerjeenucfhrhhomhepfdfnrghrrhihucfirghrfhhivghlugdfuceolh grrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmqeenucggtffrrghtthgvrhhnpedt ueduueelvdeuuddtvdffueefhefhveeiffdvfeetjeeuveeuhefhvdetjedugeenucffoh hmrghinhepvgigthgvrhhnrghlshdrihhopdhrvgguughithdrtghomhdpfehvgehlrdho rhhgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheplh grrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhm X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id D5CEF14200A2; Tue, 27 Oct 2020 12:32:15 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.3.0-529-g69105b1-fm-20201021.003-g69105b13 Mime-Version: 1.0 Message-ID: <3af046e2-2647-4b9a-907e-47c2043ad60f@www.fastmail.com> In-Reply-To: References: Date: Tue, 27 Oct 2020 11:31:55 -0500 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] Short-function syntax From: larry@garfieldtech.com ("Larry Garfield") On Tue, Oct 27, 2020, at 1:35 AM, Mike Schinkel wrote: >=20 >=20 > > On Oct 26, 2020, at 10:23 AM, Micha=C5=82 Marcin Brzuchalski wrote: > >=20 > > Hi Larry, > >=20 > > I'm wondering why we hadn't thought yet about reducing the need for = $this > > in this syntax. > > Since arrow functions have an ability to capture variables defined i= n > > parent scope why not > > think of the same for class properties which will automatically redu= ce > > short methods verbosity. > >=20 > > class X { > > public function __construct(private int $foo, private int $bar) {= } > > public function getFoo(): int =3D> $foo; > > public function getBar(): int =3D> $bar; > > } > >=20 > > And then going further why not removing =3D from arrow which indicat= ed that > > there is no return value for void functions: > >=20 > > class X { > > public function __construct(private int $foo, private int $bar) {= } > > public function getFoo(): int =3D> $foo; > > public function setFoo(int $value): void > $foo =3D $value; > > public function getBar(): int =3D> $bar; > > public function setBar(int $value): void > $bar =3D $value; > > } > >=20 > > The use of > instead of =3D> could if possible indicate the method b= eing void > > and reduce even more: > >=20 > > class X { > > public function __construct(private int $foo, private int $bar) {= } > > public function getFoo(): int =3D> $foo; > > public function setFoo(int $value) > $foo =3D $value; > > public function getBar(): int =3D> $bar; > > public function setBar(int $value) > $bar =3D $value; > > } > >=20 > > Would it be possible? > >=20 > > If not I think we should reanimate property accessors. >=20 > Which brings us back to https://externals.io/message/64469=20 > from 7 years ago. And there is=20= > this:=20 > https://www.reddit.com/r/PHP/comments/budr7q/php_74_setters_and_getter= s_have_died/ >=20 > With getters/setters, it would seem Larry's proposal might allow for=20= > more conciseness than it can with all other current syntax being the=20= > same as PHP 8.0 per Nikita.=20 >=20 > Consider this, as one straw man type of new syntax: >=20 > class TimePeriod { > private int $Seconds =3D 3600; > public float $Hours { > get():float =3D> $this->Seconds / 3600; > set(int $v) =3D> $this->Seconds =3D intval($v*3600); > } > } >=20 > Or for a different use-case with different straw man syntax that could= =20 > possibly work in addition to above syntax, where externally $Balance i= s=20 > readonly whereas internally Balance is treated like it is private so i= t=20 > can be set (I also used Michal's ">" to indicate void, although I am=20= > not sure that using a greater-than in a different context is a good=20= > idea): >=20 > class Account { > public get int $Balance; > public function Deposit(int $amount) > $this->Balance +=3D $amount; > public function Withdraw(int $amount) > $this->Balance -=3D $amount; > } Responding to several things at once here: Honestly, getters is not my primary target with this RFC. They're more = a nice side effect, given how common they are. I am more interested in = "expression functions": functions that are just a pure input->output map= . Sometimes those are methods, but frequently they're just functions. A shortened setter is not really what I'm after, therefore. If anything= , I'd prefer to make an expression that returns a new object with one ch= ange that can then be returned by this syntax, making with-er methods ea= sier. That would fit better with value objects. =20 And, in fact, named parameters already gives us something very very clos= e in 8.0: class Point { public function __construct(private int $x, private int $y) {} protected function modClone(...$args): static { $new =3D clone($this); foreach ($args as $k =3D> $v) { $new->$k =3D $v; } return $new; } =20 public function moveUp(int $amt) {=20 return $this->modClone(y: $this->y + $amt); }=20 } $p1 =3D new Point(3, 5); $p2 =3D $p1->moveUp(4); https://3v4l.org/lg4Ac That allows for a single-expression with-er method with no additional sy= ntax, just one simple utility method. Which, with this RFC, could be sh= ortened to: class Point { public function __construct(private int $x, private int $y) {} protected function modClone(...$args): static { $new =3D clone($this); foreach ($args as $k =3D> $v) { $new->$k =3D $v; } return $new; } =20 public function x(): =3D> $this->x; public function y(): =3D> $this->y; public function distFromOrigin() =3D> sqrt($this->x ** 2 + $this->y = ** 2); public function moveUp(int $amt): static =3D> $this->modClone(y: $th= is->y + $amt); } Which... I actually really like, now that I look at it. I'd rather look= at how to make modClone() more trivial or even included natively than a= dedicated setter syntax. But that's for another RFC. That's also why I don't really want to consider auto-scoping to $this. = That's unnecessary magic that would, if anything, make converting betwee= n a short and long function harder. At this point I can type $this-> fr= om pure muscle memory in a fraction of a second so I'm not too bothered = by it. :-) To Nikita's point about visual confusion in a class, that's fair. Howev= er, as noted I think it's more useful for functions anyway. Also, the p= roblem goes away if you cluster your code effectively, which is already = a good (albeit not universal) practice, and if you can use a with-er sty= le method as above. viz: class User { public function __construct( private int $id,=20 private string $username,=20 private string $role,=20 private string $firstName,=20 private string $lastName, ) {} public function getId(): int =3D> $this->id; public function getUserName(): string =3D> $this->username; public function getRole(): string =3D> $this->role; public function getFullName(): string =3D> sprintf(%s %s', $this->firs= tName, $this->lastName); public function setUserName(string $name): static =3D> $this->modClone= (username: $name); public function setRole(string $role): static =3D> $this->modClone(rol= e: $role); public function rehashPassword(): void { // ... Stuff here. } } That looks quite readable to me, and even encourages putting all the sim= ple getters together, both those that are raw getters and the "pseudo-pr= operty" ones like getFullName(). Looking at it, I quite like it both vi= sually and for what it encourages. --Larry Garfield