Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123627 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 0C17C1A009C for ; Sun, 16 Jun 2024 09:50:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1718531484; bh=EkKNbdHFkKcflhI+crKWU6z67jOGD+HiDgQkpy1UXOQ=; h=In-Reply-To:References:Date:From:To:Subject:From; b=lyWpYDRoQZfoVxpzcBZ0m4W0Lj84T5PhtTeOzewCCK6YCxZNzNs4Z3halOPVFl+3q KE8nvsLVQOdXpyse/sUVy0IaWpZ0je9bb4JBtGooHSUOYqnXyEQBjYKv4+ixEWOi/L rg6sToVn6ZvSw3zSGIgs96guu/5zrDwqZg+nG0Esw9DjB/hcAnEv9GRyzHFj1NJjDq 8hSJJ09tQRhG6RiosSgciU9fhqorvXQJ3MNNLYuzmdolBfTzVV97HItAY4q2xJkIZ5 UiRwoDXtB+ekgT46gCQVubUK1FHimXi41r3QIWmE5cdjzMcc51wy39KuIBydknQXYw Zlh+xdub8t5zg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id CD216180556 for ; Sun, 16 Jun 2024 09:51:22 +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_MISSING,HTML_MESSAGE, SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from fhigh7-smtp.messagingengine.com (fhigh7-smtp.messagingengine.com [103.168.172.158]) (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 ; Sun, 16 Jun 2024 09:51:22 +0000 (UTC) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailfhigh.nyi.internal (Postfix) with ESMTP id B45641140185 for ; Sun, 16 Jun 2024 05:50:10 -0400 (EDT) Received: from imap49 ([10.202.2.99]) by compute1.internal (MEProxy); Sun, 16 Jun 2024 05:50:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm2; t=1718531410; x=1718617810; bh=bUh8yqExXn r3D6t3SxMN0VoBUnKFdOGR8YvXzKIybiI=; b=jWDtmpeEuNo8bEthmd5LdkMraQ jMvFFITUk2AXxqv/E1O1Bm8uWeBSbT6QhULAtFjH0Jky5m+Q721K9M5R76IztRRB 4b7r+GydJJuvRDe6yeRHac4C401e5b5aiXarO9vnJJdGdPIa5YHbW3OJNtyTP8jH doQ4KSC0/o0GYI1T0mVZSIkuGUtcPY/x20TLo3E6XVeseyvCQBojwiW8QV1YfFg5 RTEUFsHcwmhAtQASo9luz7WxPp+p7n5yX8Q807EDbtSnFX9S5sEOfPX8dt4tWowD KawKtjyNzw7KBtEn5xb1zFupHvXBXFYfK0fvoeFdtpJmOxIMN2tY9HD5xa2w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1718531410; x=1718617810; bh=bUh8yqExXnr3D6t3SxMN0VoBUnKF dOGR8YvXzKIybiI=; b=S1hogIXcbNsld1gnirDrizBIneDKMa/UCJ7xrx8infK+ EYCBmz/Us0WC/vb6H0ekXjhYKozHAtJIFH3CkrHjKlXOr2Le3LqyTGAQp7L+4hmw YjDmg4qCzWNSRO1+XC37mp2Zr0qqEIYCC+M2YzW4d0vRqPF5Hj+3oKO6CTZChrfj Zjn9+CGqrjQ7DEaDE27ltDxiATRiRQ7hneLDeEEAUwR1l3HHsgnTWMjpgdFKXYtW UcEpU9vCPBLLfroefvx8CZ301YdPrY2UyMw5AIEnus16rimRW/OTUpALycblgbLU hvxYnb893dfx20YOABnz7gXRwjiJRdwGut/HybWkng== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedvfedgvdduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefofgggkfgjfhffhffvufgtsegrtd erreerreejnecuhfhrohhmpedftfhosgcunfgrnhguvghrshdfuceorhhosgessghothht lhgvugdrtghouggvsheqnecuggftrfgrthhtvghrnhepiefggeffkeeggfdvudfhheevhe fhgffgvedthfehteehleetheejheekleejjedtnecuffhomhgrihhnpehphhhprdhnvght pdgvgihtvghrnhgrlhhsrdhiohenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmh epmhgrihhlfhhrohhmpehrohgssegsohhtthhlvggurdgtohguvghs X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 4DD9D15A0092; Sun, 16 Jun 2024 05:50:10 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.11.0-alpha0-515-g87b2bad5a-fm-20240604.001-g87b2bad5 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 Message-ID: <506f21b6-6aff-41c7-930e-4621885ed724@app.fastmail.com> In-Reply-To: <04ae10a2-ceae-4996-a7fe-9b38d2f81ca2@scriptfusion.com> References: <0cf69a14-f1b5-4077-9d91-d7b579485eec@scriptfusion.com> <936e1aa3-48cc-4552-9f68-676ebcdeb596@rwec.co.uk> <04ae10a2-ceae-4996-a7fe-9b38d2f81ca2@scriptfusion.com> Date: Sun, 16 Jun 2024 11:49:49 +0200 To: internals@lists.php.net Subject: Re: [PHP-DEV] Static class Content-Type: multipart/alternative; boundary=61747049af8249f999eae94cd5f266fb From: rob@bottled.codes ("Rob Landers") --61747049af8249f999eae94cd5f266fb Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sun, Jun 16, 2024, at 11:17, Bilge wrote: > Let's start getting specific so we can make some progress. >=20 > The goals of this RFC are fairly straightforward: > =E2=80=A2 Introduce the `static` keyword at the class level to preclu= de the need to create a private constructor. That is, `__construct` woul= d be invalid in a static class. > =E2=80=A2 Prohibit instantiation of a static class with a language-le= vel error. > =E2=80=A2 Prohibit declaration of instance members in a static class = with a language-level error. > However, as ever, there's a devil in the details. In particular, we ne= ed to consider the following: >=20 >=20 > 1. Since a "static class" implies all members are static, should we = still allow explicit static method declarations with the `static` keywor= d? >=20 To keep it inline with readonly and abstract. I would look to those and = follow their rules.=20 >=20 > 2. Should `static` imply `final`? > 2a. If yes, should `final` still be allowed to be explicitly decla= red, despite being implied? >=20 I would allow it, though emit a warning that it=E2=80=99s unnecessary. T= hat=E2=80=99s what I would expect from a compiled language, anyway.=20 >=20 > 3. Should a "static class" prohibit inheritance? >=20 I would think it should be allowed. This is one of the most annoying thi= ngs about static classes in C#. That being said, PHP has traits, so stat= ic classes could theoretically use traits to provide inheritance-like be= havior. Can traits be marked static, or just classes? >=20 > 4. Should a "static class" permit state? >=20 Here=E2=80=99s the thing, there are still ways to get state even if you = disallow it (create a function called getState() that has an internal st= atic array). Using state in a static class is a code smell, for sure. Ho= wever, constants should be allowed and even those are quite limited in w= hat values they can hold. Until that gets cleared up, we should perhaps = allow variables so complex constants can exist (implementing the constru= ction of them, however, should be left as an exercise for the developer). >=20 > 5. Should traits be permitted in a static class? >=20 I hope so. Traits are some of the most abused super powers of PHP.=20 >=20 > 6. Which magic methods (if any) should be valid in a static class? >=20 Are magic methods allowed in a static context? If so, only those should = be implementable.=20 > Based on my current understanding, I would propose the following answe= rs to these questions: >=20 >=20 > 1. In order to make upgrading simple and keep method intentions clea= r, `static` should not only be valid but also required on each method de= claration, as usual for static methods. > 2. Inheritance doesn't make much sense in a purely static context, d= espite the fact that PHP has a static resolution operator; I often find = this is an anti-pattern. In any case, this is a non-BC issue if we lock = down inheritance for now and later decide to open it up. Disabling inher= itance also is in-line with the C# implementation of the same. > 2a. Since under this proposal, `final` is implied, it should not b= e necessary (or allowed) to be specified. Upgrading would be simply a ca= se of replacing `final` with `static` in-place. > 3. As already mentioned, inheritance in a purely static context does= n't make much sense, and it's a non-BC break to prohibit it and later en= able it. This decision is also in-line with the C# implementation. > 4. Perhaps the most contentious decision, we could disable state and= later enable it if there is a need, without BC. I personally cannot thi= nk of a time when I needed state in a static class. That said, I do not = agree with disabling state within the language. In case someone is relyi= ng on static state in such a class, upgrading would be impossible; they = would instead have to avoid marking the class as static, which defeats t= he purpose of this RFC. I believe we should support state, and if someon= e dislikes static state, they should enforce that with a code style rule= in their project; this is not something that should be prohibited by th= e language itself as "regular" classes already allow this. > 5. Provided a trait follows the rules of the static class (i.e. all = members are static), it seems to me this should be allowed, though I hav= e little use for it myself. > 6. Given there are many magic methods, this topic probably deserves = a separate discussion; it is not something I have spent a lot of time on= thus far so it is just included for visibility at this time. >=20 > If there are any strongly dissenting opinions on any of these points, = or any significant points I may have missed, please share. Otherwise, I = would be happy to draw up and RFC along these lines (notwithstanding I h= ave no RFC karma at present), followed by an implementation once all out= standing questions are answered. >=20 >=20 > Cheers, > Bilge >=20 >=20 > On 15/06/2024 14:53, Rowan Tommins [IMSoP] wrote: >> On 15/06/2024 12:16, Bilge wrote: >>>=20 >>> I want to introduce the `static` keyword at the class declaration le= vel. That is, the following would be valid: `static class Foo {}`. >>=20 >>=20 >> This has been proposed before, and was rejected at vote. It was nearl= y 10 years ago, so opinions may have changed, but it would be worth read= ing through the prior discussion to anticipate or counter the objections= raised, and avoid re-treading the same ground.=20 >>=20 >> - RFC: https://wiki.php.net/rfc/abstract_final_class=20 >> - Pre-vote discussion threads: https://externals.io/message/79211 and= https://externals.io/message/79338=20 >> - Final vote thread: https://externals.io/message/79601=20 >>=20 >> Searching my list archive, I find that it came up again a few months = ago, which I'd entirely forgotten: https://externals.io/message/121717=20 >>=20 >> Slightly tangential, but some of the same discussion also came up on = these rather lengthy threads about "static class constructors": https://= externals.io/message/84602 and https://externals.io/message/85779=20 >>=20 >>=20 >> Regards, >=20 >=20 =E2=80=94 Rob --61747049af8249f999eae94cd5f266fb Content-Type: text/html;charset=utf-8 Content-Transfer-Encoding: quoted-printable

=
On Sun, Jun 16, 2024, at 11:17, Bilge wrote:
Let's start getting specific so we can make some progress.
The goals of this RFC are fairly straightforward:
    Introduce the `static` keyword at the class level to preclude the need to create a private constructor. That is, `__construct` would be invalid in a static class.
  • = Prohibit instantiation of a static class with a language-level error.
  • Prohibit declaration of inst= ance members in a static class with a language-level error.

However, as ever,= there's a devil in the details. In particular, we need to consider the following:

  1. Since a "static class" implies all members are static, should we still allow explicit static method declarations with the `static` keyword?

To keep it inline with readonly and abstract. I would look = to those and follow their rules. 

<= /p>

  2. Should `static` imply `final`?
 &= nbsp;  2a. If yes, should `final` still be allowed to be explicitly declared, despite being implied?


I would allow it, though emit a warning that it=E2= =80=99s unnecessary. That=E2=80=99s what I would expect from a compiled = language, anyway. 

 = 3. Should a "static class" prohibit inheritance?

=

I would think it should be allowed. Thi= s is one of the most annoying things about static classes in C#. That be= ing said, PHP has traits, so static classes could theoretically use trai= ts to provide inheritance-like behavior. Can traits be marked static, or= just classes?

  4. Shoul= d a "static class" permit state?


Here=E2=80=99s the thing, there are still ways to get st= ate even if you disallow it (create a function called getState() that ha= s an internal static array). Using state in a static class is a code sme= ll, for sure. However, constants should be allowed and even those are qu= ite limited in what values they can hold. Until that gets cleared up, we= should perhaps allow variables so complex constants can exist (implemen= ting the construction of them, however, should be left as an exercise fo= r the developer).

  5.= Should traits be permitted in a static class?


I hope so. Traits are some of the most abu= sed super powers of PHP. 

  6. Which magic methods (if any) should be valid in a static class?


Ar= e magic methods allowed in a static context? If so, only those should be= implementable. 

Based on my current= understanding, I would propose the following answers to these questions:

  = 1. In order to make upgrading simple and keep method intentions clear, `static` should not only be valid but also required on each method declaration, as usual for static methods.
  2. Inheritance doesn't make much = sense in a purely static context, despite the fact that PHP has a static resolution operator; I often find this is an anti-pattern. In any case, this is a non-BC issue if we lock down inheritance for now and later decide to open it up. Disabling inheritance also is in-line with the C# implementation of the same.
&= nbsp;   2a. Since under this proposal, `final` is implied, it = should not be necessary (or allowed) to be specified. Upgrading would be simply a case of replacing `final` with `static` in-place.
  3. As already mentioned, inheritance in a purely sta= tic context doesn't make much sense, and it's a non-BC break to prohibit it and later enable it. This decision is also in-line with the C# implementation.
  4. Perhaps the= most contentious decision, we could disable state and later enable it if there is a need, without BC. I personally cannot think of a time when I needed state in a static class. That said, I do not agree with disabling state within the language. In case someone is relying on static state in such a class, upgrading would be impossible; they would instead have to avoid marking the class as static, which defeats the purpose of this RFC. I believe we should support state, and if someone dislikes static state, they should enforce that with a code style rule in their project; this is not something that should be prohibited by the language itself as "regular" classes already allow this.
  5. Provided a trait fo= llows the rules of the static class (i.e. all members are static), it seems to me this should be allowed, though I have little use for it myself.
=   6. Given there are many magic methods, this topic probably deserves a separate discussion; it is not something I have spent a lot of time on thus far so it is just included for visibility at this time.

If there are any strongly disse= nting opinions on any of these points, or any significant points I may have missed, please share. Otherwise, I would be happy to draw up and RFC along these lines (notwithstanding I have no RFC karma at present), followed by an implementation once all outstanding questions are answered.

Cheers,
Bilge


On 15/06/2024 14:53, Rowan Tommins [IMSoP] wrote:
On 15/06/2024 12:16, Bilge wrote:
=

I want to introduce the `static` keyword at the class declaration level. That is, the following would be valid: `static class Foo {}`.


This has been proposed before, and was rejected at vote.= It was nearly 10 years ago, so opinions may have changed, but it would be worth reading through the prior discussion to anticipate or counter the objections raised, and avoid re-treading the same ground.

= - Final vote thread: https://externals.io/message/79601 <= br>

Searching my list archive, I find that it= came up again a few months ago, which I'd entirely forgotten: https://exter= nals.io/message/121717

Slightly tang= ential, but some of the same discussion also came up on these rather lengthy threads about "static class constructors":= https://externals.io/message/84602 and https://= externals.io/message/85779


Regards,



<= /div>
=E2=80=94 Rob
--61747049af8249f999eae94cd5f266fb--