Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114187 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 44661 invoked from network); 26 Apr 2021 12:14:33 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 26 Apr 2021 12:14:33 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C0B981804BD for ; Mon, 26 Apr 2021 05:18:31 -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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, 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-yb1-f169.google.com (mail-yb1-f169.google.com [209.85.219.169]) (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 ; Mon, 26 Apr 2021 05:18:31 -0700 (PDT) Received: by mail-yb1-f169.google.com with SMTP id s9so6207613ybe.5 for ; Mon, 26 Apr 2021 05:18:31 -0700 (PDT) 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 :content-transfer-encoding; bh=PMLIrBcm5N+HA9Y+w0MWk7wLtd2lJlzm25EFw0K8xs0=; b=nE23kZ0BDghUhS9Hwaai1wXWISUv8K7yPHwos8qbVYvPIy7dGfGiYmQ2HGrsfa2PYj zDe0m2pltHN+HmeDhS5zU4oPxUxRkRRzwXPvrIorhS7xe4OUIdrer2/FXtABVsEowjMp 4G8lSIsYeQI0xp1vijon1AoEhAQ8gD1kdFJphagh6aQiSU7yhZ9dsc5Ox8as2FQKzgDI /5wX7CYAyHhQD0UwWy5iKD8Xpn3FEnilDepwkKMLjGbghcnELZTt9EEBLKcDq/CGM7R1 Sd0hlk1QzGaHp0QtBYVMbHDS9cKVD8+1EAFFlK/DDiO0UtjsMZH8UmEDD3DxSe2lsGjm XIZQ== 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:content-transfer-encoding; bh=PMLIrBcm5N+HA9Y+w0MWk7wLtd2lJlzm25EFw0K8xs0=; b=hc0gu197yit53CIQL3r1eWGRiQhQ2Ehlp/bW66yfgTIIHdpj9lH8YfLxTE8v7ftk3S jEzqaZzMIxQHp2J4pYshXrNuWaHSJ5npIctD/fpvZHMUalRHr/c5aZWrpGuha0qYUUtq pTZWVx/gQYZjefqLzPSDE3n9YxUnWewA2uIsafphcz2nZM5x85eh6c/l87uuffRGPQHw eCozBRUF9fymeD1EIY8PG3mfvNzELjurU2Twta+w9OhqornFXMzsKFniLMdd7OLYjCu2 Q+y7hmnGf+gxuk04Kp3Mys7WX6yZ/THuNjA+JsIEO8+h/tBeWNOPO2wRRvD4nHxEWD6E z9xw== X-Gm-Message-State: AOAM533zW9VD3Y7uIULwKP5I7vH7SB9h354eh1oF5uGOuP+/jNM0Gkri fnkMGOQ7UVrKJ5J1RzTZc++TcGveAA3TrERLvCxOoAkYp1tTAA== X-Google-Smtp-Source: ABdhPJyIV0KfEpcVGRnDZXFudzPUx8O+w8Fare73HGZ4BCDMgv1BGbQDCm3dZDFXI7WSClCBuqjuejBsF/Dlwcmyclk= X-Received: by 2002:a25:ab53:: with SMTP id u77mr25060164ybi.48.1619439508602; Mon, 26 Apr 2021 05:18:28 -0700 (PDT) MIME-Version: 1.0 References: <5b9f1500-615a-48f1-815f-1d48b327ef90@processus.org> <179049b1475.11134368b213512.254739612773841999@void.tn> In-Reply-To: Date: Mon, 26 Apr 2021 14:18:16 +0200 Message-ID: To: PHP Internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC][Draft] Sealed Classes From: tovilo.ilija@gmail.com (Ilija Tovilo) Hi Christian On Mon, Apr 26, 2021 at 9:54 AM Christian Schneider wrote: > > Am 25.04.2021 um 05:47 schrieb Larry Garfield : > > In practice, I think all of the use cases for sealed classes are ADT-es= que. As I noted before, combining sealed classes with Nikita's new-in-expr= essions RFC would allow for this (also using my short-functions RFC for thi= s example, although that's a nice-to-have): > > > > sealed class Maybe permits Some, None { > > ... > > > } > > > > final class None extends Maybe {} > > > > This is exactly the thing I'm worried about. > > Say I want to add something like logging to the None type. > Now your sealed and final classes prevent me from defining MyNone extendi= ng None even though it would be 100% compatible with None. Just because *yo= u* deemed that useless or wrong. The point of sealed type is to fix the number of subclasses a given type can have, which means you can handle a value by type (as that list is not finite). Code that handles Optional values could look like this: ``` if ($option instanceof Option\None) { throw new Exception(); } // We now know the value is a Some var_dump($option->value); ``` If you suddenly provide your own version of None the code above will break. This is probably more obvious when you look at the enum-equivalent. ``` enum Option { case None; case Some($value); } ``` To most people it's obvious that you can't add new cases to an existing enum. It doesn't sound sensible to add logging to a data class. That's something that belongs into a hook or service of some kind. People might also want to use sealed for behavioral classes, the use case here is the same as final. Final is not here to make your life harder. It's here to make the lives of the library maintainers easier. If they have to reason about every way a method could be overridden, every change in the library would become more risky, require more thought and more frequent major version updates. This means more work and less features for you, too. Ilija