Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119776 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 66400 invoked from network); 29 Mar 2023 15:39:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 29 Mar 2023 15:39:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B55901804F7 for ; Wed, 29 Mar 2023 08:39:54 -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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS19151 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.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 29 Mar 2023 08:39:54 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id A91C95C00E9 for ; Wed, 29 Mar 2023 11:39:53 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute4.internal (MEProxy); Wed, 29 Mar 2023 11:39:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm2; t=1680104393; x=1680190793; bh=h1tPwr1InQ fF+o1nlSoFOeE2pdQ59PDhYnQ8TTv4sz8=; b=XkVFaT4jQAMigpjn1FMGcVD6pH UTPOvoErNqyAQq4AV13W24T+8HlKZILIwGyPuJUhzoara63yEyCPvWkPobji33xu 56NgltuUjVC7IacHvO2WaDB11gu4Fzs8U2NmXmDe666tRnH60r8t40xXx+crpL2m j4blX8ukipN9i+36bNKe4O7O+0emTOJBIiAhZyElhS4ZUVP2C25hGFlGddgGw2jf gjjKt/5EomOe/3GhqP6YA0rK+ow7mq8+ZIuz81O6rFP4l5UE3iP8Yb4g7SuwhIA/ 1vs4nLjQ1TAfLFEU+1Og3Z3e4VXq8lrBZYbfkONQcz6S83Ux/rZdCGvBlDhQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1680104393; x= 1680190793; bh=h1tPwr1InQfF+o1nlSoFOeE2pdQ59PDhYnQ8TTv4sz8=; b=s x9aCThn8VE1sXyl27we7dM7l3DWxzr5snB7HMOopUbx3MYAgl8FOXhIh8X4Ph8/m uCgaol2OTeJykeRsgkMZrx2RLkYaf+Z22nL7fJd2O4Wd2j3n8bvX/vGVj8fw0gAr 93MFpaqf+xSxD/FEUx7wpGn6v2HKFVgCNoUYGUmUwE+CWvTpRuCkZCKsulFEewyQ ftovU/qrGVKf5U6uyDGN7cbz8ao9Lt+jDzm0rQWjair35gl8XmCWEKuAzdKRP1Jz VjJHAobOFgpDg70z8qiE0fcUAHOiNdgqpQivlc6klhOXfowSBwayU5wW0kW4BfwH pW3Ai4MIh78jOo1TEP75Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrvdehiedgledvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgfgsehtqhertderreejnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepueelheekffekhfelfefgleeuleeuhfevgfdvtedu keehjeevleetvdevleehjeffnecuffhomhgrihhnpehpvggrkhgurdgtohhmpdhgihhthh husgdrtghomhdpphhhphdrnhgvthenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgr mhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 64B131700090; Wed, 29 Mar 2023 11:39:53 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.9.0-alpha0-238-g746678b8b6-fm-20230329.001-g746678b8 Mime-Version: 1.0 Message-ID: In-Reply-To: References: Date: Wed, 29 Mar 2023 15:39:31 +0000 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [IDEA] allow extending enum From: larry@garfieldtech.com ("Larry Garfield") On Wed, Mar 29, 2023, at 2:25 PM, Rokas =C5=A0leinius wrote: > First, I'm pretty sure I agree now that enums should *not* be > `extend`-ed as regular classes, there's a fundamental difference as > you state - the extended enum is a fundamentally different THING as it > can hold different values - when an enum's sole purpose is to hold one > of the set of values. > > That is to say - for most implementations that's the desired case. > > I'll refer to the solution to the OP problem as ECS, Error Code System. > > For ECS, the most elegant, but also the only, solution I can come up > with - is the kind of enum that you also suggest, a `base-enum`. > `abstract enum`? > > Let me try again to describe the problem that I came here with that is > unsolvable by union types: > > 1. ECS is a *generic* component. I want to plug it into any working > system (like an existing cms). > 2. Invoking it must provide a unique ErrorCode. The existing cms has > to create an enum that will be accepted as `type: ErrorCode`. It > cannot edit the existing ErrorCode as it is part of ECS and not the > cms. > 3. There is NO special handling for the custom ErrorCode's that the > users of ECS create. We are just using the enums inferred value. > > I will keep processing this situation further, but for now it seems to= me like > > 1. Extending enums is fundamentally flawed. > 2. Basing enums off of other enums has valid usage scenarios. > > In that case, and, again, this needs way more thought to it, it's not > such a "generic way forward" that seemed to me at first and might only > provide marginal value at the cost of type complexity and that is most > probably, unfortunately, not worth it... > > (unless `abstract enum` might make sense, but my brain needs some time > off of this problem for now) > > Thank you for such a thought out discussion, everyone! 1) Please don't top-post. 2) Some good reading material for this topic, both on enums and on error= handling: https://peakd.com/hive-168588/@crell/on-the-use-of-enums https://peakd.com/hive-168588/@crell/much-ado-about-null They're not short, but that's because they are complete. :-) 3) In the error code case, the answer is to leverage the fact that enums= *do* support interfaces. interface ErrorCode { public function message(): string; } enum CommonErrors: string implements ErrorCode { case YourFault =3D 'You screwed up'; case OurFault =3D 'We screwed up'; public function message(): string { return $this->value; } } readonly class SomeoneElseError implements ErrorCode { public function __construct(privateUser $atFault) {} public function message(): string { return sprintf('%s screwed up', $this->atFault->name()); } } Now an error handling system can type against the ErrorCode interface, c= ommon errors have trivially simple enum values you can use, but you can = also make your own. In this case, you're *not* using an enum as a limit= ed-set; you're taking advantage of it being a way to predefine singleton= objects. I would consider this a completely valid use of enums, and ac= tually do something very similar in my serialization library: https://github.com/Crell/Serde/blob/master/src/Renaming/RenamingStrategy= .php https://github.com/Crell/Serde/blob/master/src/Renaming/Cases.php https://github.com/Crell/Serde/blob/master/src/Renaming/Prefix.php 4) As others have said, extending enums is a bad idea with lots of reaso= ns it's a bad idea, both conceptual and pragmatic. However, I would be = open to discussing a `use` for enums to import cases from one enum into = another. =20 There's two concerns with that to consider: A) What happens to methods on the imported enum? Are they pulled in as = well? Do interface definitions carry over? I don't know. B) The long-term goal is to expand Enums to include associated values (h= ttps://wiki.php.net/rfc/tagged_unions, although that's a bit out of date= now so don't take it as a roadmap). How would `use`-ing an enum within= another enum affect that? I have no idea, off hand. --Larry Garfield