Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119769 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 50433 invoked from network); 29 Mar 2023 13:10:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 29 Mar 2023 13:10:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BCA851804F7 for ; Wed, 29 Mar 2023 06:10:56 -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=-0.2 required=5.0 tests=BAYES_20,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, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (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 06:10:56 -0700 (PDT) Received: by mail-wr1-f45.google.com with SMTP id r29so15626375wra.13 for ; Wed, 29 Mar 2023 06:10:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680095455; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=lDzCR3TC3EZhgyAVpdXETQ+8oosO2Ohoh7wxpLzDaiM=; b=cqfyR3pl6Rz6Wig8CEtM7JfyyvZK1r9XH0u333wlOXyA5TRWMlOxfJgDxRDYEGU/6a emtiu2buS+3p/LKQe1pNZWAjOaBMrtLZXwTTvYIbLnJl3KvwSQIX0J0Jwr1beaYE/V41 y4pasgjcbQbxTumE/ksn4nX/bn85mbSk+j+GRoXBXw8oJT8dwYALzlCPuhyvcYm9c0Sc DilXu/BByWMeMdiJe3YhNHUshlxJLbvhheNqU91H51Lwf5m2IQig5k3j25429c3TBr4o Ro4bjBmjcNrkbK0ph4/e0cxnSvVWoaLwphfVh4iX6u5QRRfh34lqMOUq9Q0nrOj1l0ls zrbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680095455; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=lDzCR3TC3EZhgyAVpdXETQ+8oosO2Ohoh7wxpLzDaiM=; b=YEu5NoTOrrJfTM6ZLJtm3yhy52QnmVndgpFhUBxF7iaNA9UqJUI69OJEKzdc3lzakU /P9KiYOkrE+dbdrXgdDZ7CP6XsKL+q4WKLkQeJgmPaTb27axmRqxo7E93XOrm6iwYTHu sXwr1A3cztXNKHcWAcgv+hI7q5YOBJiNyhGXgyMKn5n39rbvf4PZO5MmNu82xfhkVBaP xO5I71Aiv+VLSEdOEZHDqmEX84VjiXrY0YcAQMQy9ae/it2Lnr8qXVjEZVYXntA19Opo KA0vtnUz7TlePd97SKQcMPAwAzGh6/h4anK203dDY23IUwmTCf5pXhv9vj0ilBj15xDo 21rw== X-Gm-Message-State: AAQBX9fp6Xqm41haKkOGRdgFS9j53VsRYMGNZWWU3pWP261u2VU7ZOWN kbfk/2gGznnD4sTsR5yxIMscueQrkdsU/c6b8lcRZMdd36g= X-Google-Smtp-Source: AKy350YBfRlQly2Vj6CBAdWbrmJ45vBkejBSq1EUglPM40GwJnPm2+YpFih4ks175m/xxOX1h13rWPgvKE9trKsDa2Y= X-Received: by 2002:a5d:4a81:0:b0:2cf:e6d0:6379 with SMTP id o1-20020a5d4a81000000b002cfe6d06379mr3999708wrq.6.1680095454829; Wed, 29 Mar 2023 06:10:54 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 29 Mar 2023 14:10:42 +0100 Message-ID: To: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000c61ed705f809b4ff" Subject: Re: [PHP-DEV] [IDEA] allow extending enum From: rowan.collins@gmail.com (Rowan Tommins) --000000000000c61ed705f809b4ff Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, 29 Mar 2023 at 13:30, G. P. B. wrote: > On Wed, 29 Mar 2023 at 09:31, Rokas =C5=A0leinius wro= te: > > Enums were implemented as final so they cannot be extended nor can exte= nd > > anything else. > > > > This is by design. > Enumerations are in type theory parlance sum types. > Objects in PHP, in general, are what are called product types. > I was just about to write a response along the same lines. I think the confusion comes because in Java-style OOP, the keyword "extends" actually does two things at once: 1. Takes the existing definition and adds to or over-rides parts of it 2. Takes the existing type and declares a sub-type What you actually want to do with an enum is: 1. Take the existing definition and add cases to it 2. Take the existing type and declare a *super-type* To give a concrete example of why, consider Christian's hypothetical: > Imagine a Randomizer is much, much slower for certain boundaries and it is decided that some programs do not care about Closed/Open but instead care more about speed. So they would want to use something like IntervalBoundary::Fastest. If we use the normal definition of "extends", we could say this: enum PerfIntervalBoundary extends IntervalBoundary { case Fastest; } Now we have an enum with three cases, which is what we wanted. But we've also declared a *sub-type*: we've said that "every PerfIntervalBoundary is-a IntervalBoundary". That means that anywhere that previously expected an IntervalBoundary, we can pass PerfIntervalBoundary::Fastest - but none of the existing Randomizer classes will know what to do with it! What we actually wanted to do is leave all the existing uses of IntervalBoundary alone, but create a new WeirdPerfRandomizer which accepts the new type. We wanted to list "PerfIntervalBoundary" as the input type, but still be able to pass it IntervalBoundary::Closed. In short, we want to say "every IntervalBoundary is-a PerfIntervalBoundary" - the relationship is the other way around. As George says, this can be implemented right now by using a union type constraint, like PerfIntervalBoundary|IntervalBoundary, which means "allow any case of PerfIntervalBoundary as well as any value of IntervalBoundary". If we wanted to support it more directly, we would need a new keyword to make clear that this is *not* a sub-type relationship - perhaps something like "expands", "allows", or "encompasses". Regards, --=20 Rowan Tommins [IMSoP] --000000000000c61ed705f809b4ff--