Newsgroups: php.internals
Path: news.php.net
Xref: news.php.net php.internals:119585
Return-Path: <deleugyn@gmail.com>
Delivered-To: mailing list internals@lists.php.net
Received: (qmail 36366 invoked from network); 21 Feb 2023 12:25:36 -0000
Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5)
  by pb1.pair.com with SMTP; 21 Feb 2023 12:25:36 -0000
Received: from php-smtp4.php.net (localhost [127.0.0.1])
	by php-smtp4.php.net (Postfix) with ESMTP id 60650180550
	for <internals@lists.php.net>; Tue, 21 Feb 2023 04:25:35 -0800 (PST)
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,
	T_SCC_BODY_TEXT_LINE 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: <deleugyn@gmail.com>
Received: from mail-ua1-f48.google.com (mail-ua1-f48.google.com [209.85.222.48])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256)
	(No client certificate requested)
	by php-smtp4.php.net (Postfix) with ESMTPS
	for <internals@lists.php.net>; Tue, 21 Feb 2023 04:25:34 -0800 (PST)
Received: by mail-ua1-f48.google.com with SMTP id x1so399161uav.9
        for <internals@lists.php.net>; Tue, 21 Feb 2023 04:25:34 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20210112; t=1676982334;
        h=cc:to:subject:message-id:date:from:in-reply-to:references
         :mime-version:from:to:cc:subject:date:message-id:reply-to;
        bh=jZhBJyrY/gx5W5MvC9P/JzAzWpgiu/pcC38Hr/cZDG4=;
        b=iCksOShhmea5MOnCT3SEt60rDoYEgl4moi4ColNknmp3q4ErUTu4n7wtWZZIgvnudw
         A+TgHdUt0h6l1aqPQlYzkmf/xx17RtMvNJulagCPwvCZUI9Wio91oA2xGU6z/SIagRNM
         5U1EDLN2Yyfz7xLlAAnf75pQw3nB4vtu5sSSRktQrhLWGBrCGHG7nebwtpXWb1KviPYc
         gwKEPr6x7M6gnvZw5VxrpKtZrE/eTvsYim2iX4paJ1+Soee5iSjOoI0MWRG0iyUfLqWC
         mLo4Ze5AnYASviLLilDZvtQoxhBN1PDEyQSdMA1iA4FNS3fmxZdBo2+DbTYFFaWdpskE
         p6Ag==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20210112; t=1676982334;
        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=jZhBJyrY/gx5W5MvC9P/JzAzWpgiu/pcC38Hr/cZDG4=;
        b=Qaf/RGxx44M9Zen0Hpbe5ldlQ5BnW74dJXNMcQHIY/b1z/24thApZSix0WV24p5HES
         bAgMnSmxsb9HuuWgQjBM9SZy5rAVVhksZ4VJeJiNs19weMo3dWu2QatecVV1WcOSwS3b
         aaEXheSSlZ54xBROT+25sFAkWhhvTypEMcBzn4hrT7k+LD+F6+GLtWmpQGEOVJ5NMVus
         AbrlNtx4PhYVqbLeEXUrrLu4VVQqzTBRVUIvvt6VrqTNl+iCGwa5W8M4vtjm7I8bn+5a
         wTGG/rdq3wa/XuH7JixdBYFB2KHXfW6I46xkXotifI+3HpsNBmXKL7rKuU+pXExvYUr4
         If9A==
X-Gm-Message-State: AO0yUKVET5KzpiKx/QubksPRAt/IGCctamLuJTPG8WgY+0ISy7/mJnvt
	bUAa8EWpCcpIBwZ/kkwGSJQoFRvOHJs1Jn7M1INKgLyw
X-Google-Smtp-Source: AK7set8zNKRI0N2GK8BjVDDKQ9zs6mrmLdKQ0p7nQe3cFWaBrjpJQK8vJ+X1l5NM4ttxrqJ+D0u/OUVlerRH5zr8n+k=
X-Received: by 2002:a1f:a706:0:b0:400:da73:a86 with SMTP id
 q6-20020a1fa706000000b00400da730a86mr829119vke.35.1676982334030; Tue, 21 Feb
 2023 04:25:34 -0800 (PST)
MIME-Version: 1.0
References: <CABAhh3Ed1uwS8bY75Rz_4FkhU4Bq7Fx0TexnLgQQcvhygcTgvQ@mail.gmail.com>
In-Reply-To: <CABAhh3Ed1uwS8bY75Rz_4FkhU4Bq7Fx0TexnLgQQcvhygcTgvQ@mail.gmail.com>
Date: Tue, 21 Feb 2023 09:25:21 -0300
Message-ID: <CADK1yX+LmLen4x2tMMj859wG5LC7S-ROauSbCXAvG4Ltm6Mhmg@mail.gmail.com>
To: someniatko <someniatko@gmail.com>
Cc: php internals <internals@lists.php.net>
Content-Type: multipart/alternative; boundary="000000000000508a5005f534e06c"
Subject: Re: [PHP-DEV] Class Re-implementation Mechanism
From: deleugyn@gmail.com (Deleu)

--000000000000508a5005f534e06c
Content-Type: text/plain; charset="UTF-8"

On Tue, Feb 21, 2023, 8:52 AM someniatko <someniatko@gmail.com> wrote:

> Hi again, internals
>
> My marathon of some crazy ideas continues :D, with less crazy one this
> time.
>
>
> ## Idea
>
> Allow "reimplementing" the non-static public API (that is public
> properties and methods, excluding constructor) of a class by other
> classes like this:
>
> ```php
> final class interface A {
>     public string $s;
>
>     public function __construct(string $s) { $this->s = $s; }
>
>     public static function fromInt(int $i): self { return new
> self((string) $i); }
>
>     public function foo(): int { return 42; }
> }
>
> final class B implements A {
>     public string $s = 'hello';
>
>     public function foo(): int { return 69; }
> }
>
> function usesA(A $param): void {}
>
> usesA(new B); // this works
> ```
>
>
> ## Explanation
>
> Consider there is a class like this:
>
> ```php
> final class Service {
>     public function __construct(private SomeDependency $dependency) {}
>     // ...
> }
>
> final class SomeDependency {
>     // ...
> }
> ```
>
> We want to write some tests for the Service class, but we don't want
> to use a real SomeDependency instance
> during tests. A common approach is to either extract an interface
> (JUST to make it testable), or to drop the
> `final` keyword and allow extending the class.
>
> Both approaches have their flaws:
>  - extracting an interface unnecessarily complicates the system, where
> only one "real" implementation of an interface is assumed.
>  - dropping the `final` keyword allows for the rabbit-hole of
> inheritance abuse, like greatly described in this article:
> https://front-line-php.com/object-oriented
>
> I believe I came up with a better idea: what if we could leave both
> benefits of prohibiting the inheritance abuse and also allow not to
> clutter our namespace with excess entities like interfaces? I hereby
> suggest to combine the responsibilities of a class and an interface
> into one thing like that:
>
> ```php
> final class interface C {}
> final class D implements C {}
> ```
>
> Now other classes can "implement" this class as well. Introduction of
> the new syntax (`class interface`) also solves BC problem - if you
> want to forbid your classes to be reimplemented whatsoever, you can
> still stick to the `final class` syntax. Although it is also possible
> to allow "reimplementing" ANY class, then new syntax is not needed -
> but some library writers like Marco Pivetta could be sad about that I
> suppose.
>
> Soo..., what do you think? Could this be a valuable addition to the
> language?
>
> Regards,
> Illia / someniatko
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php



Although I undeterstand and agree with the annoyance of both limitations
presented, I think one important factor that makes this an issue lies with
PSR-4 and autoloading. If you could declare the interface and the
implementation in the same file, as you do with Typescript, the drawback of
extracting an interface for testing would be greatly diminished.
Unfortunately undoing PSR-4 shortcomings and getting something baked into
Composer or PHP to address this seems fairly challenging.

--000000000000508a5005f534e06c--