Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112431 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 21645 invoked from network); 5 Dec 2020 19:40:12 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 Dec 2020 19:40:12 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 581B21804C3 for ; Sat, 5 Dec 2020 11:08:41 -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,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from wp160.webpack.hosteurope.de (wp160.webpack.hosteurope.de [80.237.132.167]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 5 Dec 2020 11:08:40 -0800 (PST) Received: from ip5f5bd23e.dynamic.kabel-deutschland.de ([95.91.210.62] helo=[192.168.178.29]); authenticated by wp160.webpack.hosteurope.de running ExIM with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) id 1klcv7-000579-DE; Sat, 05 Dec 2020 20:08:37 +0100 User-Agent: Microsoft-MacOutlook/16.43.20110804 Date: Sat, 05 Dec 2020 20:08:36 +0100 To: Larry Garfield , php internals Message-ID: <9CE163AC-4A9D-41C5-97B7-1710D16417AE@mabe.berlin> Thread-Topic: [PHP-DEV] [RFC] Enumerations References: In-Reply-To: Mime-version: 1.0 Content-type: text/plain; charset="UTF-8" Content-transfer-encoding: quoted-printable X-bounce-key: webpack.hosteurope.de;marc@mabe.berlin;1607195321;0c005b30; X-HE-SMSGID: 1klcv7-000579-DE Subject: Re: [PHP-DEV] [RFC] Enumerations From: marc@mabe.berlin (Marc Bennewitz) =EF=BB=BFAm 05.12.20, 16:08 schrieb "Larry Garfield" : On Sat, Dec 5, 2020, at 8:21 AM, Marc Bennewitz wrote: >=20 > * How can you access a defined case value?=20 > Something like `Suit::Spades->value()` At the moment it's only accessible via the ::cases() method. It may be= appropriate to yoink the ->value() or ->value name to access it another way= . We're debating that right now. The primitive equivalent case is tricky, because other languages have a= bout 14 different ways to think about it, all of them in the end incompatibl= e. :-) We know we don't want to just have "fancy constants," but for those = cases you do want/need a primitive instead (mainly writing to a DB or screen= ) it needs to be easy enough to get that. There's a number of competing pri= orities we're trying to balance here to make the DX as clean as possible. For me it doesn't really matter how to get the primitive value as long as t= here is a simple way to do so. As you wrote > Passing a Primitive Case to a primitive-typed parameter or return will pr= oduce the primitive value in weak-typing mode, and produce a TypeError in st= rict-typing mode. This would already break simple function calls like the following on strlen enum Suit: string { case Hearts =3D 'H'; ... public function label(): string { return 'Label of ' . $this . ' with le= ngth ' . strlen($this); } // or more clear in my opinion public function label(): string { return 'Label of ' . $this->value . ' w= ith length ' . strlen($this->value); } } To also respond to Pierre here, at present the primitives must be uniqu= e. We want to minimize the boilerplate that people have to write on every e= num for common cases, and the cases() method is part of that. It won't capt= ure everything, obviously, but if the common cases can be made trivial and t= he rare cases possible, that's a win. I agree here that the defined primitives needs to be unique as well. > * Do cases have a stable ordinal number / position and is that=20 > accessible? > This would be very interesting on implementing an optimized EnumSet= =20 > using bit-array / bit-set internally The order returned from cases() is stable as lexical order, but there's= no ordinal number to access. If you want a bit set, you could do: enum Permissions: int { case Read =3D 0x1, case Write =3D 0x10, case Exec =3D 0x100, } Right now there's no support for case ReadWrite =3D self::Read | self::Wr= ite. I don't know if that would be easy to add in the future, but I'd be OK= with it if so. Mainly this runs into the same tricky questions around prim= itive equivalent handling (and what we can coax the lexer to do). > * Is it possible to detect / type-hint if something is any enum? > ` Suit::Spades instanceof Enum` >=20 > This basically means that all enumerations would to based on a=20 > general enum. > This would be very helpful on providing functionalities especially=20 > for enumerations thinking about a doctrine enumeration type or again = an=20 > EnumSet / EnumMap. Not at the moment. We're discussing the implications of adding that. What exactly are EnumSet and EnumMap, in your mind? An EnumSet is a set (unique cases) of the same enumeration type. An EnumMap maps cases of the same enumeration type to another value. The interesting part here is that this can be done in a very efficient way = without the need to iterate over it. Like you have defined an enumeration of 200 countries enum Country: string { case USA =3D 'US', case Germany =3D 'DE', case Australia =3D 'AU', ... } $set1 =3D Country::USA | Country::Germany; // EnumSet of [Country::U= SA, Country::Germany] $set2 =3D Country::USA | Country:: Australia; // EnumSet of [Country= ::USA, Country::Australia] $set3 =3D $set1 & $set2; // EnumSet of [Country::USA] $set4 =3D $set1 & ~$set2; // EnumSet of [Country:: Germany] This could of course also be done without operator overloading but it looks= very clean with them __ All done internally using bit operations __ Greetings Marc --Larry Garfield --=20 PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php