Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112901 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 34022 invoked from network); 15 Jan 2021 17:16:15 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 Jan 2021 17:16:15 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 3423E1804DC for ; Fri, 15 Jan 2021 08:55:00 -0800 (PST) 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_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com [66.111.4.29]) (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 ; Fri, 15 Jan 2021 08:54:58 -0800 (PST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 587325C01A4 for ; Fri, 15 Jan 2021 11:54:58 -0500 (EST) Received: from imap26 ([10.202.2.76]) by compute4.internal (MEProxy); Fri, 15 Jan 2021 11:54:58 -0500 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=AXn5/RyiCe7fffLqpjjpCP2lGa437VK4pL0HB6aKB TI=; b=TbGTkiy2Aq7drVdqHGAWGenCOpPpAIi4gZFymqP6tChHBKye5B/r5fRFO lTQGatTfeyK4FlrjF6JdIHywJoE0vsgAPNfgKXeskQHdcP6Tj+7L5oU19lyNiBUa imqfpCx6vHv0HW0RJlFONr0DUcozYlZlrYz44QNeMqE4B/tYtYB0rysRtJ/2X7M6 SJ/3luhUj7UmcJcBrLfsSsIsFKywvOnHkPXjsmTLoRbIreaboKY++0FHWtpY69kz 6ruxMpKvWMNDYeMYs0o5thKOi07fOR3+xpjgPwA0JiTUkPcOWKScrGr7SU4VZuqB p8WqVnfeD0kU/V78mocb5jA/BwLtg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrtddvgdeilecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvufgtgfesthhqredtreerjeenucfhrhhomhepfdfnrghr rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh hmqeenucggtffrrghtthgvrhhnpeeggeehgfetjeehgefggefhleeugefgtdejieevvdet hfevgeeuudefleehvdetieenucffohhmrghinhepphhhphdrnhgvthenucevlhhushhtvg hrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhi vghlughtvggthhdrtghomh X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id E3D3714200A2; Fri, 15 Jan 2021 11:54:57 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.5.0-alpha0-45-g4839256-fm-20210104.001-g48392560 Mime-Version: 1.0 Message-ID: In-Reply-To: References: Date: Fri, 15 Jan 2021 10:54:36 -0600 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] "TryX" idom for Enumerations From: larry@garfieldtech.com ("Larry Garfield") On Fri, Jan 15, 2021, at 9:55 AM, Pierre R. wrote: > Le 10/01/2021 =C3=A0 22:27, Larry Garfield a =C3=A9crit=C2=A0: > > This is a little tangent from the Enums RFC, but I want to flag it b= ecause it it's the sort of in-passing decision that could have far-reach= ing implications, so shouldn't be done implicitly. > > > > At the moment, the Enum RFC for scalar enums includes two methods: > > > > public function has(string $name): bool > > > > public function from(string $name): self throws ValueError > > > > Nikita raised the point that has() seems kinda pointless as it would= only ever be used to wrap a possibly-unsafe from() call. (In most othe= r cases, calling cases() would be more useful or at least equally useful= .) One of the proposed alternatives was the following: > > > > public function from(string $name): self throws ValueError > > > > public function tryFrom(string $name): ?self > > > > The "a method that begins with try is nullable, so watch out" idiom = is present in C# and Rust, but to my knowledge has never existed in PHP.= That doesn't make it bad; it actually combines quite well with the nul= l coalesce operator to allow for default values, making a valueOrDefault= () method unnecessary. > > > > $order =3D SortOrder::tryFrom($input) ?? SortOrder::Asc; > > > > I'm not opposed to following that pattern here; it would allow both = a "hard fail" and "soft fail" variant of the operation. However, as not= ed that idiom has never appeared in PHP before that I'm aware. If we ad= opt it here, that means it will either start to spread and become a more= common PHP idiom over time, OR it won't spread and Enums will have this= weird one-off naming convention for a nullable method. The former woul= d, of course, be considerably preferable to the latter. > > > > So, explicit decision time: Are we OK with introducing that idiom, a= nd then following it consistently in the future in similar situations? = (viz, tryX() means nullable, and no-try means not nullable.) I'm good w= ith it if the consensus is good with it, but I want to see what the cons= ensus is first. >=20 > I'm OK with the tryBar(): ?Foo pattern, but my preference goes over ju= st=20 > bar(): ?Foo, as long as API are explicitly typed and correctly documen= ted. Well, the concern is that we also want to have a from(): Foo throws Valu= eError version, but both cannot be called from(). The possible patterns are: Interface: Suit::from(string): ?self Usage:=20 $s =3D Suit::from($var) ?? Suit::SomeDefault; Interface: Suit::from(string): self throws ValueError Suit::has(string): bool Usage: if (Suit::has($var)) { $s =3D Suit::from($var); } Technically, one could create the second from the first more easily than= vice versa, but both could implement each other. try { $s =3D Suit::from($var); } catch (ValueError) { $s =3D Suit::SomeDefault; } // or $s=3D Suit::from($var) ?? throw new ValueError(); While the nullable return ?? is very appealing, we know from experience = that most people don't think to check the null case, leading to unhelpfu= l "method called on non object" errors 6 months later when someone passe= s in bad data. An Optional/Maybe type is the ideal solution as that for= ces people to account for that possibility, but we don't have those yet.= (Enums are a step toward being able to build them cleanly.) A thrown = exception is next, although nothing forces people to include the try-cat= ch so they could forget that, too. At least static analyzers tend to wa= rn you about it. Nullable is least likely to get handled in practice, e= ven if the resulting code may, in all honestly, look the cleanest if you= 're OK with ??. Offering both exception and nullable variants is a compromise option, bu= t that requires disambiguating the names somehow. TryX -> nullable is t= he least-bad suggestion so far, IMO. I'm still not sure of how we want to proceed. :-/ > I will not fight against or for any or another solution, as long as th= e=20 > convention remains the same for everything. >=20 > Larry, I think your proposal is missing something: if a convention=20 > emerge, it should be documented as such, and be considered as a law fo= r=20 > subsequent language / API addition, the real question, IMHO, is : Are=20= > people OK with writing naming and design conventions by law in PHP cor= e ? >=20 > For that matters, I'm OK, this would avoid many bikesheds in the futur= e:=20 > this is the law, and the law says, name it tryX(), no more useless=20 > votes, no more flavor-oriented flame wars on naming :) While such a formal convention would be nice, that's a separate fight, a= nd the last time I picked that fight (https://wiki.php.net/rfc/php_names= pace_policy) we lost. :-) For now I just want to keep enums de facto co= nsistent. --Larry Garfield