Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125351 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 5817B1A00BD for ; Thu, 29 Aug 2024 22:02:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1724969081; bh=/V/eCN2uFmh/BtJp2fLUYUihUuWrd90oVgEg6UyI9wc=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=ile5nmULK4a379oXkKsujpRNHFwuFEmSi/mjJM/9cUS7HVugKlmGsNCWu51M7U+iF CEApZsUHIsaO8S43bgHE3Lj3E98N0paAw4QEJtkGuMXLqzPgDUtSGCxCoSXPvv0UUB AypsjS+H67xDrqaeDUseY05nmQohIR1ML9jY8BCaoisuutlvkm3SAZyi1rL01fB1rN bCtjIGTzoW8Xiv79dsRBWksOqh3s7QKZbtQkmVRy9KFibXumO4OtvRobQV9KlI0F50 RK3Gix6RXoV+VwM//2o4M9GgBSQyMpT37H71kLkJTg4T97tVa0IZbPWsQjG2TelW20 QV/h9GO1Jrukw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 075AE180086 for ; Thu, 29 Aug 2024 22:04:40 +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.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS,T_KAM_HTML_FONT_INVALID autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 ; Thu, 29 Aug 2024 22:04:39 +0000 (UTC) Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-428e0d18666so9746075e9.3 for ; Thu, 29 Aug 2024 15:02:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724968964; x=1725573764; 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=j4Ps7kzbG2t4kyLAb/QaAZO3W8TjKZ8MrOcXpN8rQGo=; b=ncm+F7eGrTUxI67mrtZi3w9pTbLXFNWcHHBKltG/eixbGpDoYqQf2HQnDNX7a1aQW1 HeHUsj9GFsezKHTV+VS+T/GemHxEbpI8fSejL+hhs84zx1PG4Cf490+AUGX/eBUTb68g zBx8mnHGrCcCIA3YPsEqdakCnSUiwbAsv4SCSkLt+D9zqLHWKu59AGkK3TMdmud5VYi0 CY437BNLT9y+8kzMrpJZTstg9fam/wkz+KSLgulNI090WjiMSrP4dp+5s+iYd95CHgku 9NrAl1lRpaHPK3n3e/aMMDyqyf+g9PwfoiVtep2/VA8jH7N92Zi+EFLl5+HLlaksW9zj C9hg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724968964; x=1725573764; 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=j4Ps7kzbG2t4kyLAb/QaAZO3W8TjKZ8MrOcXpN8rQGo=; b=DX06fg5vq5Wt25yMkodZxjlCENtcn2rKv2vlh1geve58kwFEYdsc+RyfYuWoIpmtR1 bIxWLLHGv91pnsR2m4foZ4LkmmLdy1jJdCvv7KliBaMw+qicl2tyxRvCB2cK3qdIp7ik rt1v14OaD+bodLQ9t4Un656iLGpnw0ztQYPasXqM1fi6FtkF1f1Xv9An6b3iFx17sHzV J/s1L/+Hlgd1uUNhpe3hlSIwl03DOOynCn6e4iOjUH9Drn1Zr/NUDOEVeOYaC6tknHDa yDFMSYmpM6C0MAkz5irJ4Z2FIxG9yFnzznAzctdV3Ylbh36/CpPig55knUpv0Lw+hDN7 zSfg== X-Gm-Message-State: AOJu0Yz37HJkceiU/6B1YbGsOK3eOViwqml6YIOdagc7/xh8H+8ERJFi zHrrm9oZyB2cxe5uTeO8JKFX/kn8Ub4Jjhqn4OGKGSFq78B0lnr5X7nJLhxa+q3MkzLv6sA0Q0Q v1Sszw86bu+zYVoZngeBl5xV10A== X-Google-Smtp-Source: AGHT+IGARF9UPDPiSpWPZoXj86sbOdyqaNU9+LV3m0xNyYCN5Pe1MwbAXd8rBzfiH5Hji5SyHVNs460ZaVY5WTSLVWs= X-Received: by 2002:a05:600c:198e:b0:42a:ab31:c248 with SMTP id 5b1f17b1804b1-42bbb206518mr1530785e9.14.1724968963053; Thu, 29 Aug 2024 15:02:43 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Fri, 30 Aug 2024 01:02:31 +0300 Message-ID: Subject: Re: [PHP-DEV] [Discussion] Implementing interfaces via traits To: Brent Roose Cc: PHP Internals Content-Type: multipart/alternative; boundary="0000000000004a9ee80620d9a266" From: udaltsov.valentin@gmail.com (Valentin Udaltsov) --0000000000004a9ee80620d9a266 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, 27 August in 2024=E2=80=AFat 10:31, Brent Roose wrote: > Good morning internals > > I=E2=80=99d like to test the waters about an RFC idea: allowing traits to > implement interfaces, and consequently a class that uses such a trait wil= l > automatically implement the interface as well. > > The original idea comes from Rust, where traits can be used as types. I > read a very inspiring post suggested by Larry, on the topic of =E2=80=9Cc= lassic > inheritance=E2=80=9D vs the way Rust and Go approach it [1]. The tl;dr is= that both > Rust and Go solve several pitfalls of classical inheritance (the diamond > problem and inheritance abuse), thanks to a much simpler approach. In > Rust=E2=80=99s case that is by using traits. If you have the time, I high= ly > recommend reading that post, it=E2=80=99s super interesting and it gives = a lot of > good arguments for rethinking inheritance. > > Back to PHP, using traits as types seems impossible, since traits are a > compile-time copy/paste mechanism, which means there=E2=80=99s no type in= formation > available about them at runtime. > > However, allowing traits to implement interfaces would solve this problem= : > these interfaces would be copied over to classes during compile-time, and > the interface=E2=80=99s type information is available at runtime. On top = of that, > traits already have well-defined rules for conflict resolution, so we > wouldn=E2=80=99t need any additional syntax to handle edge cases. > > Even though PHP traits differ from Rust, PHP developers already seem to > like the idea of being able to =E2=80=9Cattach a type to a trait=E2=80=9D= one way or > another. Let me name a couple of things that happen today: > > > - > > Laravel often provides =E2=80=9Cdefault implementations=E2=80=9D for t= heir interfaces > via a trait [2]. As mentioned before, traits already deal with > conflict-resolution, so method collisions aren=E2=80=99t a blocker. > - > > Both PHPStan and Psalm have an annotation that forces trait users to > implement an interface [3], which is essentially the feature I=E2=80= =99m > describing, albeit via docblock annotations instead of proper syntax. > - > > Even though it was not accepted, the interface default methods RFC > approached the problem from a different angle [4]. While a majority > disagreed that interfaces should implement their own methods directly,= I > remember it was a heavily debated topic, and believe that approaching = it > from the other side might be easier to accept. > > > In the end, the goal of this RFC would be to promote a =E2=80=9Cnew way= =E2=80=9D of > inheritance, which is described in depth in that post I mentioned earlier > [1]. It=E2=80=99s a different programming style, but I think there are go= od > arguments to be made for it, even though it will likely not be everyone= =E2=80=99s > cup of tea. Modern languages like Rust and Go show that there=E2=80=99s m= erit in > rethinking classical inheritance, and there are signs that the PHP > community is open to it as well, given the examples with Laravel=E2=80=99= s default > implementation traits, static analyser support, as well as the interface > default methods RFC last year. > > If internals are open to the idea, I would like to draft a proper RFC for > it. Please let me know your thoughts! > > Brent > > Links: > > > - > > [1] https://lwn.net/Articles/548560/ > - > > [2a] > https://github.com/laravel/framework/blob/11.x/src/Illuminate/Auth/Aut= henticatable.php > - > > [2b] > https://github.com/laravel/framework/blob/11.x/src/Illuminate/Contract= s/Auth/Authenticatable.php > > - > > [2c] > https://github.com/laravel/framework/blob/11.x/src/Illuminate/Contract= s/Auth/MustVerifyEmail.php > - > > [2d] > https://github.com/laravel/framework/blob/11.x/src/Illuminate/Auth/Mus= tVerifyEmail.php > - > > [3a] > https://phpstan.org/writing-php-code/phpdocs-basics#enforcing-implemen= ting-an-interface-for-traits > - > > [3b] > https://psalm.dev/docs/annotating_code/supported_annotations/#psalm-re= quire-implements > - > > [4] https://wiki.php.net/rfc/interface-default-methods > > Hi, Brent! Let me link another relevant discussion about adding `@(phpstan|psalm)-require-implements` to the core: https://externals.io/message/116802 . --=20 Valentin --0000000000004a9ee80620d9a266 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Tue, 27 August in 2024=E2=80=AFat 10:3= 1, Brent Roose <brent.roose= @jetbrains.com> wrote:

G= ood morning internals


I=E2=80=99d like to test the waters about an= RFC idea: allowing traits to implement interfaces, and consequently a clas= s that uses such a trait will automatically implement the interface as well= .


The original idea comes from Rust, where traits can be used as t= ypes. I read a very inspiring post suggested by Larry, on the topic of =E2= =80=9Cclassic inheritance=E2=80=9D vs the way Rust and Go approach it [1]. = The tl;dr is that both Rust and Go solve several pitfalls of classical inhe= ritance (the diamond problem and inheritance abuse), thanks to a much simpl= er approach. In Rust=E2=80=99s case that is by using traits. If you have th= e time, I highly recommend reading that post, it=E2=80=99s super interestin= g and it gives a lot of good arguments for rethinking inheritance.

Back to PHP, using traits as types seems impossible, since traits are a co= mpile-time copy/paste mechanism, which means there=E2=80=99s no type inform= ation available about them at runtime.


However, allowing traits = to implement interfaces would solve this problem: these interfaces would be= copied over to classes during compile-time, and the interface=E2=80=99s ty= pe information is available at runtime. On top of that, traits already have= well-defined rules for conflict resolution, so we wouldn=E2=80=99t need an= y additional syntax to handle edge cases.


Even though PHP traits d= iffer from Rust, PHP developers already seem to like the idea of being able= to =E2=80=9Cattach a type to a trait=E2=80=9D one way or another. Let me n= ame a couple of things that happen today:


  • =

    Laravel often provides =E2=80= =9Cdefault implementations=E2=80=9D for their interfaces via a trait [2]. A= s mentioned before, traits already deal with conflict-resolution, so method= collisions aren=E2=80=99t a blocker.

  • Bot= h PHPStan and Psalm have an annotation that forces trait users to implement= an interface [3], which is essentially the feature I=E2=80=99m describing,= albeit via docblock annotations instead of proper syntax.

  • <= li dir=3D"ltr" style=3D"list-style-type:disc;font-size:11pt;font-family:Ari= al,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-nu= meric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;= vertical-align:baseline;white-space:pre-wrap">

    Even though it was not accepted, the interface default met= hods RFC approached the problem from a different angle [4]. While a majorit= y disagreed that interfaces should implement their own methods directly, I = remember it was a heavily debated topic, and believe that approaching it fr= om the other side might be easier to accept.


In the end,= the goal of this RFC would be to promote a =E2=80=9Cnew way=E2=80=9D of in= heritance, which is described in depth in that post I mentioned earlier [1]= . It=E2=80=99s a different programming style, but I think there are good ar= guments to be made for it, even though it will likely not be everyone=E2=80= =99s cup of tea. Modern languages like Rust and Go show that there=E2=80=99= s merit in rethinking classical inheritance, and there are signs that the P= HP community is open to it as well, given the examples with Laravel=E2=80= =99s default implementation traits, static analyser support, as well as the= interface default methods RFC last year.


If internals are open to= the idea, I would like to draft a proper RFC for it. Please let me know yo= ur thoughts!


Brent


Links:



Hi, Brent!

Let me link another relevant disc= ussion about adding `@(phpstan|psalm)-require-implements` to the core: https://externals.io/message/11= 6802 .

--
Valentin
--0000000000004a9ee80620d9a266--