Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126494 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 18B271A00BC for ; Mon, 24 Feb 2025 14:05:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1740405799; bh=qAzr7aKzha+lgor5JxanVWo0j0/J2JSin1NBRI11QtE=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Lt9H7wR90TR/YtwLUPyRY3vKjpnHxvzcGtrmjcCNxgnCHDBQ95gkU7q3Hy1sypqOp OMS594Qo6weM2G67gz2HBJ+HO1NJKZenkp9xN4bgYp2o2/b3Y9d7hkaQd34xG6QJTD hvO5nV7bRh2QkqIh91fqmOe2ld0Hz4jnx3/bOA8HkRQONrojCanWk0+qopymvXHipl w++5Fnz2coE9hIYvgJ2aPy42BC+snQ5rFJ8fqVhuwJ2J+B3Xo+6DNSUHpa8RWRiCQf OkAfFaCk12cJN9G++YQltrLeaOoZh3jeUBOYcasNHjD3cKpGvif4DR4fK9SyRbHb77 65LiSbYC9rx0g== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 5003D18059D for ; Mon, 24 Feb 2025 14:03:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_20,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, FREEMAIL_REPLY,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=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.50]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 24 Feb 2025 14:03:10 +0000 (UTC) Received: by mail-oo1-f50.google.com with SMTP id 006d021491bc7-5fcd7d306f3so3663768eaf.3 for ; Mon, 24 Feb 2025 06:05:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740405949; x=1741010749; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=ABBUFadK071EoBb34LdeDc93kih0xm9j8fnGhvwk7Bk=; b=dFNPLP2AyGw5N33Wb5CE1bp9LCRIRqOCCo5G8x0t95ChBwpzbDHaaPOV/0KWYGWjhy 4hH6VZeo+Vx/OahkbQbNwEd2uxtbZMSCxL1sCl1j01YLDPRmjRxJOXmMCf5esmXQcK0E dFp8OIfyuNi5AcKkgTkht/fMy73r+J4JgMHruYKQ9YOIX4aTN2gX+LtxkXPvXAv7bqX7 nueLl7sNPFXgcQUXifO7C4DtI/kVZyadYSMznfwUZZyQd8ZWrDemEiFFbfsIBSIih7Cn tgeMfJES9RNeRjcP5I/66NcaBr26Pm40nUi+NpJmn4GxtjpaPZD0BJ9SGihXnPDx1fGO afmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740405949; x=1741010749; h=cc: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=ABBUFadK071EoBb34LdeDc93kih0xm9j8fnGhvwk7Bk=; b=Ie+xYrcKJsa9LJbfwZ1zoDKi2C9YSzdjWu66rUrcrFy96SemwU+a1BZ0XXmGkeASGT D2S9qLRZzrfvZmAy9q+WdZGWndJzqKYFoJWc4rMO2iPt6oxRo/n4oTIf6tL2lE1TB7nk eEmihQLmWYFnPBAnHcifJ1unOlh/iX0CuQ4PivIqvr0CJL5FvEN1jZ5y9wkD7xWWLE8z lRryfSZY+wT0ZQm6idO4ZRK4aHJa7pNOGuL8+bva5ceZJXYosnSMPgo4qn7AzxSo2ytt yBc4LhGHIgEshe9osXqXsIZSprsRQTiw/aaoQBeRV6tyZYNAOk5QLkfpYFCliNRq4sfV wwXQ== X-Forwarded-Encrypted: i=1; AJvYcCWpP1Yb8muU+88KAbGmF50z1ZuG9i6mryEqHmx+ZqrGx/JOTnBKaIo+0TqggCpGEAid8T4ECFcgc4Q=@lists.php.net X-Gm-Message-State: AOJu0YxMyNzBTZO2WYdGhGi8400E0IdFUElosonhde8GLTJW5PdECtKl G5m5VKtETRgTOsfXnXZbQ7yAUXlwARu0sX0KjOuf4YZQ1tpYSn9lRD75vdVEtGOqkF1+P0V4CYS YVA5gQdMf3GgrxDZRPZEvwKalA0PaNlfz X-Gm-Gg: ASbGncsqOli4YiJxt/rWuOVGymqfwcXn7CGITOBa5HskjfIjQJiO3sZA/9KyPIj1q6+ mL1vkYSxlHCOnq4PT4eLAEwiNb8t9T59leeeP4giCQdVphqESl8DdSOcPouD7jqIEfcwuF8RILf TdGomnhi3z/OjArnq/8l/kleGYsEdO3Wn8BerwrdR9 X-Google-Smtp-Source: AGHT+IE3Cd4HC3brc+kSxUOkuv/MLfqd8SbCHzyqcFQZGJe5FyBpqeMsRnmf/6WVIjYRm/HXRmWdsauBs5Bz/RpuImM= X-Received: by 2002:a05:6820:2299:b0:5fc:f9b4:7f48 with SMTP id 006d021491bc7-5fd19504c6fmr9149587eaf.1.1740405948644; Mon, 24 Feb 2025 06:05:48 -0800 (PST) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <1BCB4144-231D-45EA-A914-98EE8F0F503A@automattic.com> <8E614C9C-BA85-45D8-9A4E-A30D69981C5D@automattic.com> <9bf11a89-39d9-457b-b0ea-789fd07d7370@gmail.com> In-Reply-To: Date: Mon, 24 Feb 2025 07:05:37 -0700 X-Gm-Features: AWEUYZkERrMmORsiun9Vvt66k4NWPfHMi9aTNBzPhXRIftZmVWHw_3dSXJBBiog Message-ID: Subject: Re: [PHP-DEV] [RFC] [Discussion] Add WHATWG compliant URL parsing API To: "Gina P. Banyard" Cc: Nicolas Grekas , internals@lists.php.net Content-Type: multipart/alternative; boundary="0000000000005590a1062ee3d69a" From: hamiegold@gmail.com (Hammed Ajao) --0000000000005590a1062ee3d69a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable What's wrong with declaring all the methods as final eg. https://github.com/lnear-dev/ada-url/blob/main/ada_url.stub.php On Mon, Feb 24, 2025, 7:00=E2=80=AFa.m. Gina P. Banyard = wrote: > On Monday, 24 February 2025 at 11:08, Nicolas Grekas < > nicolas.grekas+php@gmail.com> wrote: > > I'm seeing a push to make the classes final. Please don't! > This would badly break the open/closed principle to me. > > When shipping a new class, one ships two things: a behavior and a type. > The behavior is what some want to close by making the class final. But th= e > result is that the type will also be final. And this would lead to a > situation where people tighly couple their code to one single > implementation - the internal one. > > The situation I'm telling about is when one will accept an argument > described as > function (\Uri\WhatWg\Url $url) > > If the Url class is final, this signature means only one possible > implementation can ever be passed: the native one. Composition cannot be > achieve because there's no type to compose. > > Fine-tuning the behavior provided by the RFC is what we might be most > interested in, but we should not forget that we also ship a type. By maki= ng > the type non-final, we keep things open enough for userland to build on i= t. > If not, we're going to end up with a fragmented community: some will > tightly couple to the native Url implementation, some others will define = a > UriInterface of their own and will compose it with the native > implementation, all these with non-interoperable base types of course, > because interop is hard. > > By making the classes non-final, there will be one base type to build upo= n > for userland. > (the alternative would be to define native UrlInterface, but that'd > increase complexity for little to no gain IMHO - althought that'd solve m= y > main concern). > > > The open/closed principle does not mean "open to inheritance". > Just pulling in the Wikipedia definition: [1] > > In object-oriented programming, the open=E2=80=93closed principle (OCP) s= tates > "software entities (classes, modules, functions, etc.) should be open for > extension, but closed for modification"; > > > You can extend a class by using a decorator or the delegation pattern. > But most importantly, I would like to focus on the "closed for > modification" part of the principle. > Unless we make *all* the methods final, inheritance allows you to modify > the behaviour of the methods, which is in *opposition* to the principle. > > Moreover, if you extend a WhatWg\Uri to behave differently to the WhatWg > spec, then you do *not* have a WhatWg URI. > Which means the type becomes meaningless. > > Quoting Dijkstra: > > The purpose of abstracting is *not* to be vague, but to create a new > semantic level in which one can be absolutely precise. > > > A concrete WhatWg\Uri type is abstracting over a raw string. > And it creates a new semantic level where when you are in possession of > such a type, > you _know_ with *absolute* certainty how it behaves and what you can do > with it, and know that if a consumer needs a WhatWg URI it will not rejec= t > it. > This also means consumers of said WhatWg\Uri type do not need to care > about validation of it. > > If one is able to extend a WhatWg URI, then none of the above applies, > and you just have a raw string with fancy methods. > I.e. you are now vague, and any consumer of the type needs to do > validation because it ***cannot*** trust the type, and you have created a > useless abstraction. > > It also seems you did not read the relevant "Why a common URI interface > is not supported?" [2] section of the RFC. > The major reason why this RFC has had so many iterations and been in > discussion for so long is because M=C3=A1t=C3=A9 tried, again and again, = to have a > common interface. > But this just does not make any sense, you cannot make something extremel= y > concrete vague and abstract, unless you want to lose all the benefits of > the abstraction. > > Best regards, > > Gina P. Banyard > > [1] https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle > [2] > https://wiki.php.net/rfc/url_parsing_api#why_a_common_uri_interface_is_no= t_supported > --0000000000005590a1062ee3d69a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

What's wrong with declaring all the methods as final eg.= https://github.com/lnear-dev/ada-url/blob/main/ada_url.stub.php


On Mon, Feb 24, 2025, 7:00=E2=80=AFa.m. Gina P. Banyard <= ;internals@gpb.moe> wrote:
= On Monday, 24 February 2025 at 11:08, Nicolas Grekas <nicola= s.grekas+php@gmail.com> wrote:
I'm seeing a push to make the classes final. Pl= ease don't!
This would badly break the o= pen/closed principle to me.

When shipping a new class, one ships two things: a beha= vior and a type. The behavior is what some want to close by making the clas= s final. But the result is that the type will also be final. And this would= lead to a situation where people tighly couple their code to one single im= plementation - the internal one.

<= div class=3D"gmail_attr">The situation I'm telling about is when one wi= ll accept an argument described as
function = (\Uri\WhatWg\Url $url)

If the Url class is final, this signature means only one po= ssible implementation can ever be passed: the native one. Composition canno= t be achieve because there's no type to compose.

Fine-tuning the behavior provi= ded by the RFC is what we might be most interested in, but we should not fo= rget that we also ship a type. By making the type non-final, we keep things= open enough for userland to build on it. If not, we're going to end up= with a fragmented community: some will tightly couple to the native Url im= plementation, some others will define a UriInterface of their own and will = compose it with the native implementation, all these with non-interoperable= base types of course, because interop is hard.

By making the classes non-final, th= ere will be one base type to build upon for userland.
(the alternative would be to define native UrlInterface, but that= 'd increase complexity for little to no gain IMHO - althought that'= d solve my main concern).

The open/closed principle does not mean "open to = inheritance".
Just pu= lling in the Wikipedia definition: [1]

In obj= ect-oriented programming, the open=E2=80=93closed principle (OCP) states &q= uot;software entities (classes, modules, functions, etc.) should be open fo= r extension, but closed for modification";

You can extend a class by using a dec= orator or the delegation pattern.
But = most importantly, I would like to focus on the "closed for modificatio= n" part of the principle.
Unless = we make *all* the methods final, inheritance allows you to modify the behav= iour of the methods, which is in *opposition* to the principle.
Moreover, if you extend a WhatWg\Uri to behav= e differently to the WhatWg spec, then you do *not* have a WhatWg URI.
Which means the type becomes meaningless.<= /span>

Quoting Dijkstra:

<= blockquote style=3D"border-left:3px solid rgb(200,200,200);border-color:rgb= (200,200,200);padding-left:10px;color:rgb(102,102,102)">
The purp= ose of abstracting is not to be vague, but to create a new semantic = level in which one can be absolutely precise.
=

A concrete WhatWg\Uri type is abstracting over a raw s= tring.
And it creates a n= ew semantic level where when you are in possession of such a type,
you _know_= with *absolute* certainty how it behaves and what you can do with it, and = know that if a consumer needs a WhatWg URI it will not reject it.
This also means consu= mers of said WhatWg\Uri type do not need to care = about validation of it.
=
<= span>If one is able to extend a WhatWg URI, then none of the above ap= plies, and you just have a raw string with fancy methods.
=
I.e. you are now v= ague, and any consumer of the type needs to do validation because it ***can= not*** trust the type, and you have created a useless abstraction.

It also seems you= did not read the relevant "Why a common UR= I interface is not supported?" [2] section = of the RFC.
The major reason why this = RFC has had so many iterations and been in discussion for so long is becaus= e M=C3=A1t=C3=A9 trie= d, again and again, to have a common interface.
But this just does not make any sense, you cannot make something = extremely concrete vague and abstract, unless you want to lose all the bene= fits of the abstraction.

Best regards,

Gina P. Banyar= d
--0000000000005590a1062ee3d69a--