Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114222 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 58743 invoked from network); 27 Apr 2021 23:54:08 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 27 Apr 2021 23:54:08 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 480B21804BD for ; Tue, 27 Apr 2021 16:58:32 -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,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-ot1-f50.google.com (mail-ot1-f50.google.com [209.85.210.50]) (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, 27 Apr 2021 16:58:31 -0700 (PDT) Received: by mail-ot1-f50.google.com with SMTP id z20-20020a0568301294b02902a52ecbaf18so4544823otp.8 for ; Tue, 27 Apr 2021 16:58: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 :cc; bh=IbA3HcaoZ66H5ITGKWsRv0SVCV/2IA0NHWHJ8XNPQAU=; b=MWNbVztmqi0Kh/mphKka3wDuBlewrOlfd9XYSEuB9IEaufo3Ne4u4DVqJf1EEjNOry yPEJFtY4kQfk/DqP5k959poEShTcEQSlAgwgBIYhSoaLTSiRI2nLA/ZysUroH3yGPxTz fIBeHhEeVUzbMZ/RR5gXqmYIMdg0pn8tFXsSdh8/nwnW3KiNu1G/5e9ds5j987IIlEtM b6WVppeUnlFamQZoxOdEV71ZGKR5Gj5K4YKtpss2g0CnpCpabLVjztLBwMJ80ZeD4Qgt lQcZmOdddMyYmy0GMXKqmKneOZmPvwdoOQK1fp+mT0eF22B0UaAaM5WNVC5KkWic+2EI 3OYA== 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=IbA3HcaoZ66H5ITGKWsRv0SVCV/2IA0NHWHJ8XNPQAU=; b=iOdP0L16hCJR9yOHq9ywHpeK7J448o952HMIf473gR/00LqPefwRtnyXMYwYRoJfI5 2aqdj9mfThNLb6wX8L5oFFfrrXqrAGB8mBoKEpWpT1XXlJ8uP2lVScTk3StvhZV35AP5 PmRYt4Y4x9YC/lBvl2GVh11O2lQ1StmuQT7GxdOn9AG0k3/D6SSTqnOHhMGwRNtXN4uD WalZHc7nWf8yfoLX6PHdTmGF20SK3CmpcNiNJvCTjqZwZz+szgu89e4AXypYB2W67P9B SOJJT9+bxkgz7yl7ZfrUBwL1Hu5PvdjmVFLLYovCk5keULNRHa3t7u1DnIpJ1pN4BM09 Kjpg== X-Gm-Message-State: AOAM531MaL3zuAIMANPqRCdA6GFpyFWzXkvQsKMeWIZIPYdhoum5jsMo sDuXnyXN8bHVfb8IRyjlVdeGofhfHJG2QW1sNXc= X-Google-Smtp-Source: ABdhPJxkjS3cx9+NebfBDun145qHMW/NDNZ39FUkY54smJCiy1TAkJ3qso1CQ5E3RI9MBeNnXLzvwr9oJj3GGkgIm7c= X-Received: by 2002:a9d:425:: with SMTP id 34mr21885935otc.25.1619567911213; Tue, 27 Apr 2021 16:58:31 -0700 (PDT) MIME-Version: 1.0 References: <5b9f1500-615a-48f1-815f-1d48b327ef90@processus.org> <179049b1475.11134368b213512.254739612773841999@void.tn> <722ed544-69e3-3be4-f828-185914617228@processus.org> <51fffd88-03c7-463d-a6d7-94c086cb5893@www.fastmail.com> In-Reply-To: Date: Wed, 28 Apr 2021 00:58:19 +0100 Message-ID: To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="000000000000099d4605c0fd0a1b" Subject: Re: [PHP-DEV] [RFC][Draft] Sealed Classes From: davidgebler@gmail.com (David Gebler) --000000000000099d4605c0fd0a1b Content-Type: text/plain; charset="UTF-8" Okay, I promise I'll make this my last word on the thread, for the sake of my own sanity and at this point, I'm sure that of others - first, I really appreciate your explanation there for why you consider this RFC a good thing, so thank you for that. Personally, my objections still stand for in essence the same reasons as before; 1. In respect of data modelling, you may think you've understood a model such that its sum is closed, this may even be true for your use case (and yes, agree both that this is useful and some other languages have better ways of expressing it) but sometimes, it is only true until it isn't. E.g. you have said colours are red, green and blue. This is fine until someone else needs to reason about purple and can't because your data model says there is no purple. 2. A (non-functional) attribute [or other syntax/convention] for sealed does not / should not be interpreted as saying "pretty please, don't extend me", it says "I don't endorse/support this, but if I haven't accounted for your use case and you're confident you understand your problem, hey, don't let me stand in your way" - other interpreted languages (Python comes to mind) use this approach very effectively and their ecosystems are not automatically riddled with bad models as a result. Indeed PHP is in some respects unusually strict for an interpreted language (though I am not saying that is necessarily a bad thing). 3. That there are valid use cases for a language construct does not mean people will only use it for those cases - I'd go as far as to say they definitely won't. Annotation in some form is safe in all use cases, fatal errors aren't. So I stand by the real, primary benefit of these constructs - delineation of intent boundaries - is achieved without creating a construct which introduces a new fatal error condition. Anyway, yeah - I've said my piece(s) and I'm not a voting member so what I think doesn't matter to that end. I hope my input on internals discussions is not entirely moot, though; just like everyone else I take part because I'm very fond of PHP and have an interest in its future. Appreciate those who are willing to hear me out. On Wed, Apr 28, 2021 at 12:00 AM Larry Garfield wrote: > On Tue, Apr 27, 2021, at 5:48 PM, David Gebler wrote: > > On Tue, Apr 27, 2021 at 11:23 PM Larry Garfield > > wrote: > > > > The two options to prevent such errors are: > > > > > > 1. Sealed classes. > > > 2. Extend Enums into ADTs. > > > > > > > Unless I've misunderstood your example, there is a third option which > quite > > possibly prevents the error in a nicer, easier to reason about, more > > flexible pattern. > > > > class Perhaps extends Maybe implements OperatesOnTheValueInterface { ... > } > > If we were dealing with a service object in classic OOP (viz, OOP based on > classes), then yes, turning the function into a method and using > polymorphism would be the correct answer, rather than RTTI. > > However! Classic OOP design patterns are not all that PHP supports, and > that's a good thing. The "class" construct, for better or worse, is the > syntax for logic objects, value objects, data objects, and control flow > objects (such as Maybe, Either, etc.), plus assorted other patterns that > are not part of the classic OOP canon. But they're still good and useful > patterns, and often a better model than classic OOP "polymorph all the > things" approaches. > > If we were designing PHP from scratch today, I'd argue for having separate > language constructs for funcy-syntax-closures (which is what service > objects are), product types (structs, value objects, all the same thing), > and control flow types. Many newer languages do differentiate those > better. That's not where we are, though, so we're stuck with class being > the uber-syntax for anything even slightly interesting from a type > perspective. So be it, but it does lead to ample confusion about which use > case you're talking about, especially when not everyone is familiar with > all of the different, distinct use cases. > > See also: This thread. :-) > > Sealed classes are... not really useful at all for service object use > cases. They are useful for product type and control flow type use cases. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > --000000000000099d4605c0fd0a1b--