Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116136 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 63306 invoked from network); 22 Sep 2021 14:40:03 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 22 Sep 2021 14:40:03 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 5D2E31804A9 for ; Wed, 22 Sep 2021 08:21:15 -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_H2,SPF_HELO_NONE,SPF_PASS 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-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) (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 ; Wed, 22 Sep 2021 08:21:14 -0700 (PDT) Received: by mail-ed1-f48.google.com with SMTP id c22so11015285edn.12 for ; Wed, 22 Sep 2021 08:21:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=sLfysqWVWOxaHB2fmQxSh3NoykB1xIUvzfDq8Cs7TxM=; b=KsZGbtw0xI1gzRK0nQCep/1JxRgdkbqkoShCtI9iJtXx+dZjMoTO2q3aVpmRpgRBoT NsLuHdH3+wehKDiRLBR/bdt8J3AGd1umADK7eJibLY0Y9MqatWTidXQUgUDvtrmkS2dG rEZxyO71FBUJY3pTSedMMq76Q8KJakPNSsa8CFeM8Paf1Uf1QLRvOs4RE0c6vbUdJD2G KgCu4SI3y5N6WwlGlIeEOozDPRNDiyhQnVha6ZCsJIpasZLu9PSjs0qFIww8oSSbL1JW OIrHHufIhtqya2cKZHB3H4Mnm/rLamGPX0/SoxdD8U+/88/YKlZnw0kgDmpTW+fLGHir RyIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=sLfysqWVWOxaHB2fmQxSh3NoykB1xIUvzfDq8Cs7TxM=; b=bCwGqA6eXKaHSg4VQtqdR0DTxK149yYBadnTkH2IGsi2RVvcSQot/pgj1n76VGnyKU zb91Pd9PYRZ2dm7jqxTmDK2pmJAsJWaa+5zYGVR+fK23LeSeP+RKCFD6OcrriJzIXl5P SmtvXIqp32/G6GYlBz1uKEadx/I7FfPV0CNDldPAh0f9reVHhjOaXiXMKt1prU1svV/L aGw15+skoTZkqSa7otTI9TYct6pOGHmyRh3bzXZtuZvqW/PCzoY8p3v7AfQm+t5YJetC eVpNXKLOLoJJ9JmeZY4+hAq7H8qro2bV3co6jdSUYRqRFtzHHIFSnobna6Llh/Mbz7K6 K8fQ== X-Gm-Message-State: AOAM531gvpXLptVefGujjyMFinPmVajpwH51oRzzzsHHockM+HpxraJ4 Fu+IyPdM4rQa1KL/465C5ajtqG/qOyF7Hbg8mEY= X-Google-Smtp-Source: ABdhPJx1mCKV1ENFSmvO+BVC10qr7mab0+BRvTlUMgjdUWBsRfHLBaDWrkp64p/cm/hh0aBO8Nr9CM/lhgzsHBni4Jw= X-Received: by 2002:a50:d84c:: with SMTP id v12mr126532edj.203.1632324072423; Wed, 22 Sep 2021 08:21:12 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 22 Sep 2021 16:21:01 +0100 Message-ID: To: "Matthew Weier O'Phinney" Cc: PHP Developers Mailing List Content-Type: multipart/alternative; boundary="0000000000007ec56405cc9710f8" Subject: Re: [PHP-DEV] BC breaking changes in PHP 8.1 From: george.banyard@gmail.com ("G. P. B.") --0000000000007ec56405cc9710f8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, 22 Sept 2021 at 15:24, Matthew Weier O'Phinney < mweierophinney@gmail.com> wrote: > On Wed, Sep 22, 2021 at 9:01 AM G. P. B. wrote= : > >> On Wed, 22 Sept 2021 at 14:30, Matthew Weier O'Phinney < >> mweierophinney@gmail.com> wrote: >> >>> Yesterday, I opened an issue regarding a change in the pgsql extension = ( >>> https://bugs.php.net/bug.php?id=3D81464). >>> >>> PHP 8.0 introduced the concept of "resource objects". Where previously = we >>> would have resources, and use `get_resource_type()` when we needed to >>> differentiate various resources, resource objects give us immutable >>> objects >>> instead that allow us to type hint. Personally, I think this is >>> wonderful! >>> >>> The rollout for 8.0 was incomplete, however, and only touched on >>> something >>> like 4-6 different resource types. Still, a good start. >>> >>> With PHP 8.1, we're seeing the addition of more of these, and it was >>> encountering one of those changes that prompted the bug I previously >>> linked >>> to. >>> >>> Here's the issue: while overall, I like the move to resource objects, >>> introducing them in a MINOR release is hugely problematic. >>> >>> Previously, you would do constructs such as the following: >>> >>> if (! is_resource($resource) || get_resource_type($resource) !=3D= =3D >>> $someSpecificType) { >>> // skip a test or raise an exception >>> } >>> >>> Resource objects, however: >>> >>> - Return `false` for `is_resource()` checks. >>> - Raise a warning for `get_resource_type()` checks, and/or report the >>> resource object class name =E2=80=94 which differs from the previous re= source >>> names >>> in all cases. >>> >>> This means conditionals like the above BREAK. As a concrete example, I >>> did >>> PHP 8.1 updates for laminas-db last week, and assumed our postgres >>> integration tests were running when we finally had all tests passing >>> successfully. However, what was really happening was that our test suit= e >>> was testing with `is_resource()` and skipping tests if resources were n= ot >>> present. We shipped with broken pgsql support as a result, and it wasn'= t >>> until test suites in other components started failing that we were able >>> to >>> identify the issue. >>> >>> Further, the "fix" so that the code would work on both 8.1 AND versions >>> prior to 8.1 meant complicating the conditional, adding a `! $resource >>> instanceof \PgSql\Connection` into the mix. The code gets unwieldy very >>> quickly, and having to do this to support a new minor version was >>> irritating. >>> >>> When I opened the aforementioned bug report, it was immediately closed = as >>> "not an issue" with the explanation that it was "documented in >>> UPGRADING". >>> >>> This is not an acceptable explanation. >>> >>> - There was no RFC related to 8.1 indicating these changes were >>> happening. >>> (In fact, there was no RFC for resource objects in the first place =E2= =80=94 >>> which >>> is concerning considering the BC implications!) >>> - In semantic versioning, existing APIs MUST NOT change in a new minor >>> version, only in new major versions. >>> >>> Reading the UPGRADING guide, there's a HUGE section of backwards >>> incompatible changes for 8.1 =E2=80=94 THIRTY-FOUR of them. Nested in t= hese are >>> notes of around a half-dozen extensions that once produced resources no= w >>> producing resource objects. >>> >>> The pace of change in PHP is already breathtaking when you consider lar= ge >>> projects (both OSS and in userland); keeping up with new features is in >>> and >>> of itself quite a challenge. Introducing BC breaks in minor versions >>> makes >>> things harder for everyone, as now you have to figure out not only if >>> there's new features you want to adopt, but whether or not there are >>> changes that will actively break your existing code. I strongly feel th= at >>> anything in the backwards incompatible section of the UPGRADING guide >>> should be deferred to 9.0, when people actually expect things to change= . >>> >> > >> Resource to object conversions have precedent for not being in a major >> version: >> GMP in PHP 5.6 >> Hash in PHP 7.2 >> >> The fix to how to check these conditions is the same as last year and it >> is to check against false, not is_resource nor an instance of the class. >> It is true that if you ensure that the resource type is correct it gets >> slightly unwieldy but: >> >> if ($resource !=3D=3D false && ((is_resource($resource) && >> get_resource_type($resource) =3D=3D=3D $someSpecificType) || $resource i= nstanceof >> ClassName) ) { >> // skip a test or raise an exception >> } >> >> Should be identical to the changes made to support PHP 5.6, 7.2, and 8.0 >> in regards to the other conversions, and I don't see why it is now an is= sue. >> We also *explicitly* hold off from pouring more of our time in resources >> to object conversions during the Beta cycle of PHP 8.0 as we knew we cou= ld >> defer this to a later minor version, compared to promotions from E_WARNI= NG >> to Exceptions which took a huge amount of last summer. >> >> PHP tries to broadly follow semantic versioning but it *never* has >> adhered to it strictly, and this is not uncommon within programming >> languages nomenclature (e.g. Python). >> >> Moreover, many changes to php-src are based, and a result of this >> refactoring from resources to objects, so it isn't just a simple "revert >> commit", especially as we are in the RC phase. >> >> Albeit this is only my opinion, this is still not a bug, and I frankly >> don't think any of it should be reverted as we, the core team, are never >> going to be able to convert all of the resource to objects in time for a >> major release, except if we decide that each year PHP is getting a major >> release and we throw minor versions out of the windows. >> > > With changes like this, though, PHP is **already** de facto doing major > releases every year. > > If internals buys the argument Kamil makes that "PHP does not follow > semantic versioning", then: > > - Stop using semantic versioning numbers, as the numbers lead to > (appropriate) user expectations about stability. > - Or start numbering versions properly, and call each minor a new major, > so users know what to expect. > I'm sorry but this is nonsense, we don't use semantic version numbers, they might look like them but they are not. All of the version names of Python, Golang, Ruby, and TypeScript just to name a few *look* like semantic versioning but are not. Example for Python: https://docs.python.org/release/3.9.0/whatsnew/3.9.html#removed Example for Golang: https://golang.org/doc/devel/release#policy Example for Ruby: https://github.com/ruby/ruby/blob/v2_5_0/NEWS#label-Compatibility+issues+-2= 8excluding+feature+bug+fixes-29 Example for TypeScript: https://devblogs.microsoft.com/typescript/announcing-typescript-4-2/#breaki= ng-changes And a non programming languages example Spring Boot doesn't adhere strictly to semver either [1] So I sincerely hope you're also telling these projects to change their naming scheme, just so that it cannot be mistaken as semver. As a sanity check I looked at the migration guide of every single version of PHP from PHP 5.0 onwards, and all had some BC break in a minor version, so I don't know why you're touting this as an issue *now*. > As somebody who's been contributing to and maintaining OSS libraries > forever (since 2002), the pace of change of PHP is, frankly, ridiculous. = I > can keep up with patches. I can keep up with new features. But BC breaks > EVERY YEAR just creates churn. I've spent most of the past 18 months doin= g > nothing but ensuring libraries work on new PHP versions. I then get users > angry that they aren't getting new features; if I don't update to the > latest PHP version, I get other users angry they can't use the library on > the newer PHP version. And with new PHP versions every year... I > essentially have to update every 2-3 years regardless, and will lose user= s > if I don't do it every year. > > Figure out what the BC breaks are going to be, and do them all at once. > It's far easier for the ecosystem to adapt to a big drop of BC breaks eve= ry > 3-5 years than it is every year. > I don't think any of us can look into the future and just "figure out" what the BC breaks are going to be, because if we could I'm pretty sure we wouldn't be introducing those issues in the first place. Moreso, PHP is also an open source project, so people work on what they want and when they want to, which such "clean-up" tasks might get boring for folks. Something I would imagine that you should now, as you've been in the community for two decades. I'd also point out that the only reason the BC breaks are now every year is not because we randomly decided to, but because of the fixed yearly release schedule which was introduced with PHP 7. So, should we now go back to a random release cycle where we release a version when it is deemed ready, and go back to the criticism that the language is stagnating? I'll add that some of these BCs are a prerequisite for some features, we might be able to mitigate it to some extent, see the readonly properties kafufle with WordPress, but this is not always guaranteed. > Again, I DO like the resource objects feature. But getting a few here and > there over many minor releases is a lot of breakage to track and adapt to= . > And that's just the tip of the iceberg. > Again, breakages are not a new thing, so I don't see why you are pointing this out now. And FYI the resource to object migration has a tracker [2] and is for the most part complete, with the exception of streams, which due to the heavy engine works which needs to be done, can probably only happen for a PHP 9.0 release. > There=E2=80=99s merit to spacing it out - I doubt anyone wants another PH= P 7 flag >> day again. >> >> (Ask the Python people how they feel about moving all the breaking >> changes to a single release=E2=80=A6) >> > > I can tell you now a lot of us OSS maintainers would prefer it to yearly > updates. We are also an OSS project, so my question to you, do you fundamentally break compatibility between two major versions of your project so that people cannot upgrade to the new version without a full rewrite? Because this is what Python 2 to 3 was, and many project did *not* upgrade from one version to another and Python has only dropped support for Python 2 after 10 years, and there are still loads of projects which didn't make the upgrade. Therefore, why on earth should we as a project shoot ourselves in the face by making it so daunting to upgrade with a 500 bullet item list of BC breaks in one version compared to spanning it out over multiple years. > It might be a good idea not to assume, and instead actually do some > scientific polling of users and ecosystem library/framework maintainers. > Based on my conversations with other maintainers in the ecosystem, my > experience is not isolated by any means. On top of that, I get to analyze > the annual Zend user surveys, and the number one reason for people being = on > older PHP versions (and > 50% of respondents are, EVERY YEAR) is the cost > of upgrading. Clearly, there's a perception that something is broken with > the current approach, and internals is ignoring it. > How can we ignore something when this seems to be the first time this is a major complaint? > BTW, another good possibility, recommended by somebody responding to a > twitter thread I started around this issue: work with RectorPHP to provid= e > a ruleset for each minor release, to ease upgrades. It's far easier than > having to read through an UPGRADING guide and having to figure it out for > yourself. I'd argue these should be in place as soon as a beta is ready. > Sure, where is the money to pay someone to do this? Best regards, George P. Banyard [1] https://developer.okta.com/blog/2019/12/16/semantic-versioning#phil-webb-sp= ring-boot [2] https://github.com/php/php-tasks/issues/6 --0000000000007ec56405cc9710f8--