Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112764 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 21033 invoked from network); 5 Jan 2021 14:50:52 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 Jan 2021 14:50:52 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id CBF4D1804D4 for ; Tue, 5 Jan 2021 06:27:05 -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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (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 ; Tue, 5 Jan 2021 06:27:05 -0800 (PST) Received: by mail-lf1-f54.google.com with SMTP id 23so72902491lfg.10 for ; Tue, 05 Jan 2021 06:27:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=4gfvlnER1mxyz8JYk4saITPwCnYHsCsHOlYWXrtxCCg=; b=B7zzK8t1Bfdbv+jI+qmqdjzaagLYnCcqtmBaeLqYWw7flx6zdxwzMIz0zrscZXJb15 6nFXri28YWax1T1xXkgfkVSuJtp5Kk+8sw19nf2LmtiQbE47LcxlCciD6MCNwGL35ywO phx5y2+4WZZuaqwUDsTx5ifEwzXKLGOL53pXX+1okd+eIJ8qAyurdJg3srJn6d3DCrko YDWP1Xio6Cq/9faglKg6H0StLAcgyW0GWDfFPTldyGxwe7J7vi+SIzf+HzaL4Ym53CAf INe0jX4UE6hofo+Ir77Xh0HlbMEUzn9r7O61xDvAMGtc8acURaDuyer1CBCdMvLU7+9Y 4mKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4gfvlnER1mxyz8JYk4saITPwCnYHsCsHOlYWXrtxCCg=; b=IEJUCFGEpzVfFbhRmVlAH0ZP3zTPjDMo9EYwLvKQhHCAOekrkfh4D0jd5e5WIQelM/ A58R2/a1HftHNH0Fm9+3SfZ9/RLXWBD4rgX5e+PhRsRx2pt4MDD/I2FgSTnuV+6EY9c/ zGVixWzfe9n6XWlbMUE9BVeZlMk0SyYZS8KhoqjRpjIasBLiPOVSXbLMl6XKhqS/dRVf aHW0jOmwW8lOYH5ox3R3YD9hQwUbYiH3evVRexqGi1eW8Ix45tnfB+IAoV9KN0Dw4bsi UX0J7b/wfIT+1+88qM7TYmZvm8vOUQBru7BmjdUYoi3kJTcyvayg5rMyrjFjJorHEwrs cO8w== X-Gm-Message-State: AOAM530Pkyx8yevo/12sLbRpkLIpeb4gr9HJdfdi+yO9X5gdamQBUjCq 2WxYKg3Ag2cl8+bDC0QBacyG+JeGrYZhC3LCaz1eXTLfPNPYww== X-Google-Smtp-Source: ABdhPJwScwgknPMh/KSPnFDxDPsaXJ/lVFDyKVG2RK6NU4f6jzwhOe80shahxUa/KQaMAMmPebPVYzI4om0gbwfSTwA= X-Received: by 2002:a2e:8eda:: with SMTP id e26mr36850861ljl.272.1609856822038; Tue, 05 Jan 2021 06:27:02 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 5 Jan 2021 15:26:46 +0100 Message-ID: To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="00000000000004559c05b828007a" Subject: Re: [PHP-DEV] [RFC] Enumerations, Round 2 From: nikita.ppv@gmail.com (Nikita Popov) --00000000000004559c05b828007a Content-Type: text/plain; charset="UTF-8" On Mon, Dec 28, 2020 at 9:22 PM Larry Garfield wrote: > Hello, Internalians! > > After considerable discussion and effort, Ilija and I are ready to offer > you round 2 on enumerations. This is in the spirit of the previous > discussion, but based on that discussion a great deal has been reworked. > The main change is that Enumeration Cases are now object instances of the > Enumeration class rather than their own class. Most of the other changes > are knock-on effects of that. > > Of particular note: > > * Cases may not have methods or constants on them. They're just dumb > values. > * Enums themselves may have methods, static methods, or constants. > * Traits are supported, as long as they don't have properties. > * The value() method on scalar enums is now a property. > > The full RFC is here, and I recommend reading it again in full given how > much was updated. > > https://wiki.php.net/rfc/enumerations > > The implementation is 98% complete; there's still a few lagging bits in > reflection, and some opcache bugs that Ilija is still stomping on. > > There are a few outstanding questions listed that we would like feedback > on. We're not entirely certain which direction to go with them, for > reasons explained in the RFC. Input on those is especially welcome. > > Happy New Year. May it be enumerable. Nice work, I like the updated proposal. Some notes: > Similarly, enum names and case names are both case insensitive. I agree that enum names should be case insensitive (like class names), but why should case names be case insensitive? The closest analogon to a case would be a class constant, and those are case sensitive. > All Cases have a read-only property, case, that is the case-sensitive name of the case itself. I can see how this makes sense, but it wouldn't be my first guess as to how you access the case name. I'm wondering if using $enumValue->name or $enumValue->caseName might be preferable. > Scalar equivalent values must be literals. Constants and constant expressions are not supported. Why? This seems inconsistent with the overall language. If I can use a constant expression as a class constant value, why can't I use it as an enum value? > ScalarEnum exposes an additional static method from() that is automatically generated. I think it would be good to be slightly more explicit here and call it fromValue(). (We could have fromName() to construct it from a case name, and any number of custom from* named constructors.) > The from() method will up-cast from a scalar to its corresponding Enumerated Case. Invalid scalars with no matching Case will throw a ValueError. There is also a has() method, which will return boolean true if a case with that value exists and false otherwise Just a thought, but rather than having has() and from(), it may make sense to have from() (throws if invalid) and tryFrom() (returns null if invalid). I think a has() method is pretty much useless in isolation, it will always be used in a combination of has() and from(), in which case it is better to combine them rather than have an implicit contract between them. > Manually defining a static from() or has() method on a Scalar Enum will result in a fatal error. Or a non-static one :) You can't define a static and a non-static method with the same name in PHP. > Enums and cases may have attributes attached to them, like any other language construct. The TARGET_CLASS target filter will include Enums themselves. The TARGET_CONST target filter will include Enum Cases TARGET_CONST should presumably be TARGET_CLASS_CONST. More generally though, I wonder if there should be a separate TARGET_CASE... > Returns the scalar equivalent type of the Enum, if any. If it doesn't have one, it returns a ReflectionType on null. Possibly I'm misunderstanding the sentence, but why does it return a "ReflectionType on null" rather than just "null"? It's not like ::$value will have a null value in this case, it will not exist at all. > Additionally, a new function is_enum(mixed): bool returns true if the value passed is an enum or case object. Could you please clarify what "an enum or case object" means? Is this function both for checking whether an object is a case object and a (string) class an enum class? Some typo/etc notes on the text: > All Unit Enums as implemented as instances of their enum type. "as" -> "are" possibly? > That is one way to determine an Enum from any other object: "determine" -> "distinguish" possibly? > The above hierarchy is logically similar to the following class structure (although this is not the actual code that runs): You might want to change the constructor to private function __construct(public string $case) {} in this example. The use of "new static" for a final class is also confusing. Regards, Nikita --00000000000004559c05b828007a--