Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114153 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 24531 invoked from network); 25 Apr 2021 16:42:18 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 Apr 2021 16:42:18 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 354BA1804B5 for ; Sun, 25 Apr 2021 09:46:05 -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.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) (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 ; Sun, 25 Apr 2021 09:46:04 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 5D6D71633 for ; Sun, 25 Apr 2021 12:46:03 -0400 (EDT) Received: from imap8 ([10.202.2.58]) by compute4.internal (MEProxy); Sun, 25 Apr 2021 12:46:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; bh=J7yufSzxMFlW43R7NF8KIg5zmnhMjGY/Um+bWjVN+ kk=; b=rkSCZgJ0Fc5pLqZGZw2yVSXlREFAqcWhgMsv+03CuOKPXz6rW8+8aEQPX 2zA0Hs+TWdzw+gvURsB5XA9+WFENuDROF8PVUvASZLhyCoJDl9s+pcWcAnHkubY3 G3lLO8EUBHzTcA8YISr68fJXq42IeQQDNE1xlx3140nQcaIc/VYGiZG6rYRBfYdL XSaeIaEvF149fEJdhGZOczElrf1GNIlWpintQX5moqNLfKGwA+RaKnsiLxt5+pL0 i0LENRhgtxjzEtIq0Usy8TlBoHEeFHgyK2MTwb9j/W8Oe0vO5PnKFhy5JLzQRZum dKz13mlz6fwcP5qu50aeaGqTO/03A== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdduiedguddtjecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtgfesthhqredtreerjeenucfhrhhomhepfdfn rghrrhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrd gtohhmqeenucggtffrrghtthgvrhhnpeeiieelhffgtefhieevtdduiedvjeffudeuhfdt tdefleegleegffeluefhtdffvdenucffohhmrghinhepshhtrggtkhhovhgvrhhflhhofi drtghomhdpphhhphdrnhgvthenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhep mhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 86B923A02D2; Sun, 25 Apr 2021 12:46:02 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.5.0-alpha0-403-gbc3c488b23-fm-20210419.005-gbc3c488b Mime-Version: 1.0 Message-ID: In-Reply-To: <179097c0182.121a28de2250923.6774005422437895662@void.tn> References: <5b9f1500-615a-48f1-815f-1d48b327ef90@processus.org> <179049b1475.11134368b213512.254739612773841999@void.tn> <179097c0182.121a28de2250923.6774005422437895662@void.tn> Date: Sun, 25 Apr 2021 11:45:42 -0500 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC][Draft] Sealed Classes From: larry@garfieldtech.com ("Larry Garfield") On Sun, Apr 25, 2021, at 9:43 AM, Saif Eddin Gmati wrote: > ---- On Sun, 25 Apr 2021 08:39:37 +0100 Olle H=C3=A4rstedt=20 > wrote ---- >=20 > > > In practice, I think all of the use cases for sealed classes are=20= > ADT-esque.=20 > > > As I noted before, combining sealed classes with Nikita's=20 > new-in-expressions=20 > > > RFC would allow for this (also using my short-functions RFC for=20= > this=20 > > > example, although that's a nice-to-have):=20 > > >=20 > > > sealed class Maybe permits Some, None {=20 > > >=20 > > > public const None =3D new None();=20 > > >=20 > > > static public function Some($x) =3D> new Some($x);=20 > > >=20 > > > public function value() =3D> throw new NotFoundException();=20 > > >=20 > > > public function bind(callable $c) =3D> static::None;=20 > > > }=20 > > >=20 > > > final class None extends Maybe {}=20 > > >=20 > > > final class Some extends Maybe {=20 > > > private $val;=20 > > > private function __construct($x) { $this->val =3D $x; }=20 > > >=20 > > > public function value() =3D> $this->val;=20 > > >=20 > > > public function bind(callable $c) =3D> new static($c($this->val= ));=20 > > > }=20 > > =20 > > Yes, the Maybe/Option type is a good example! Because you know ther= e=20 > > will never be another extension. But it's worth noting that wheneve= r=20 > > you do *not* know that, these concepts suffer, even in functional=20= > > programming, by the same issues as I mentioned before with regard t= o=20 > > maintainability - you can't easily extend it without touching old=20= > code=20 > > (there are attempts to fix this by making algebraic datatypes=20 > > extensible, but it didn't get widely adopted AFAIK). Also see this=20= > > thread about the expression problem:=20 > > https://stackoverflow.com/a/871375/2138090=20 > > =20 > > Disregarding the limitations of maintainability, the real power of=20= > > algebraic datatypes is of course the pattern matching functionality= =20 > > seen in OCaml and Haskell. I'm leaning towards tagged unions +=20 > pattern=20 > > matching have more to offer PHP than sealed classes (and even more=20= > so=20 > > when pattern matching can be extended with guard clauses and=20 > catching=20 > > exceptions). The RFC author(s) might want to extend the RFC to=20 > reflect=20 > > the relation to tagged unions, and how they overlap (or not)?=20 > > =20 > > Olle=20 Pattern matching as it's currently being worked on would apply to arbitr= ary objects with visible properties, and enums are, in the engine, "just= objects." So both a sealed class with public properties (or rather, pr= operties visible in the scope) and an Enum with properties added (tagged= unions/ADTs) would look the same to pattern matching. Naturally that R= FC has to get finished first, but assuming it is, it would apply either = way. (Discrete but complementary components FTW.) > As mentioned in a previous email (=20 > https://news-web.php.net/php.internals/114134 ), there's many=20 > differences between ADTs and Sealed classes, > and in my opinion that's enough to have them both in the language as=20= > personally i have use cases where ADTs won't work. Many differences in terms of their implementation details, yes. Ilija l= ays out a good list of those in that email. However, they do address th= e same conceptual problem space. Is there anything that ADTs or sealed classes would enable that the othe= r one simply couldn't? If we can get a list of those, that can help us = determine which is the ideal route to pursue or if there really is value= in adding both despite their heavy overlap. (The list of links you had before lacks enough context for me to figure = out what you're suggesting, sorry. Please provide more precise comparis= ons of the two here.) ---------- Also, another syntax suggestion: final class Foo permits Bar, Baz {} class Bar extends Foo {} `final` already indicates that a class is inextensible. Sealed classes = are poking holes in that guard. Essentially, final on its own is an ext= ension cardinality of 0, sealed classes offer an exception list to that = to give a precise cardinality list. The main advantage here is that it introduces only a single new keyword,= not multiple. If `permits` were replaced with `for` (as the RFC alread= y offers), it would be no new keywords. Minimizing new keywords is gene= rally a good idea anyway.