Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123856 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 D6E821A009C for ; Wed, 26 Jun 2024 05:51:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719381174; bh=uJ4d55etTMq1BbHu0GpmG4qENb4RiT23lkGNxmMwoBE=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=dQztuZQnFlWSDhJu/MoBWD1YLcgDlfum1550WbLs/quc5sGvT+80F2qfHCdRHwjj9 BCD6tPu+b9oMhyrRdjaIi67kM5OMn0jUDquuUV7/15R+kFCHLZH3cgNJzatNr/Keqh 9gXh1veTOaX1daZuKl+x8Egw/SrNEV0goOiW7/Co98eOWoZ2vZirYil1CTJ0YbllKe 8VFkZRZrI6fvukdIcrA+V+Z+Mtcnq9pDW2vAqaR/LnDrbEIrXbR0W7FpOMvupnCFpp mLP4yNiGKVfbCXkjKVRsblJ5aO/fz/xWCD42eT9GHtSl8EQNqlIi7QmYk2dDakbNRP MdSbLKCu6wx5Q== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0D46E18003F for ; Wed, 26 Jun 2024 05:52:54 +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_50,DKIM_SIGNED, DKIM_VALID,DMARC_MISSING,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,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 mail-yb1-f169.google.com (mail-yb1-f169.google.com [209.85.219.169]) (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 ; Wed, 26 Jun 2024 05:52:53 +0000 (UTC) Received: by mail-yb1-f169.google.com with SMTP id 3f1490d57ef6-dfab5f7e749so5693074276.0 for ; Tue, 25 Jun 2024 22:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1719381095; x=1719985895; darn=lists.php.net; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=NGw1zBj6qSgTGMLrGvbBjOGLrubiSyDhVZ4CtacNg7c=; b=hblkRDG5jDFXZxYnNhCgQnzYALPZqd8eY6ji6tX8LPHpqlsHR4tpqUAsEvfVfdvlMP 7xwY1kD06JoZtf29usXEUeyt9fdW9xJ6DnEG7gvQ0zYrTWU/ZJ2xnRyODW5v2XIBi7IA 07nfOGD04bhMvBv6ZNi2cdUHvPbXn7y5IYWzV0GRLc/bE08yW2PEJO7cMeM2/ct3v7cl aOAy8hEg4IRleTabq+gt2hm0e4kUXGDEDi7ldfBKi48o0rsfOavAa61G1aMhkBU0CdxZ ap35ub5IiIvDMwArvLh/yFx1byclPYvexTzF2EHZwvY0QVvfhaFfXzN5OuifId4HkWEL FWVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719381095; x=1719985895; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NGw1zBj6qSgTGMLrGvbBjOGLrubiSyDhVZ4CtacNg7c=; b=RlWtN9kaRcfmCPGTBcfyNbL4QhyWUlzTQ5xfG1MkOOQAUyUzPkiBmsxLQLyIDQsxAz 3QIZbfVGiqTiog8UN9nDqOA7plA16TfCrzNtmlnTbA+pU+KK/OPl92RA2S+fjfwtdoI9 oZv1eQ/HnH3+sA4fGtzA+hE+PSAdcYdb1afSCemZ/3iRmx2VhvLF4thXeF2yp9ietS2F dRB4CndXVilLfr480BW4OoHic4OVJQIs/35/aFxiuRbZGGQYXBKyxzdfXcn7pQHromgf rZ1hQGVmNa1wNeWP//aPxlQhSdD9MVlqu1QRigVH+Ln4X3xkxiFH9ICI3zJFKUcs+YzK +WOw== X-Forwarded-Encrypted: i=1; AJvYcCXhAnaWTPZoQ3WvjxFN9qXTSZEvwRvQohkQ/X7cjmCVXJDMDvp9hms4YUF6mM65A28SuiYAJdImOMaHrCKHLZwlXrWo3zOmDQ== X-Gm-Message-State: AOJu0Yzh/lo5T+WdUDOuD40WN/GQu7xYC1ZXWK+AZ39iyJ0FfTqDnErP KuIDLQrnXl5XAVJia/+2NKXXBB7qtSvcv8iagy5aEm8xgUx0GDCRAZ/m3s6z+N4= X-Google-Smtp-Source: AGHT+IGyAxS+Ch12uzc3JNUgbtRAz6rNxet+L8cQhGra0ODxntkyFjkBavlCEhBli2zVVfs7Rx42Tg== X-Received: by 2002:a05:6902:342:b0:e02:5433:d8a4 with SMTP id 3f1490d57ef6-e030107c9f3mr10534270276.46.1719381095414; Tue, 25 Jun 2024 22:51:35 -0700 (PDT) Received: from smtpclient.apple (c-98-252-216-111.hsd1.ga.comcast.net. [98.252.216.111]) by smtp.gmail.com with ESMTPSA id 3f1490d57ef6-e0310efda8csm1875995276.8.2024.06.25.22.51.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 25 Jun 2024 22:51:34 -0700 (PDT) Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_9A9C983E-5EDF-4965-8ABE-B11D66081208" Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.8\)) Subject: Re: [PHP-DEV] [RFC] Static class Date: Wed, 26 Jun 2024 01:51:33 -0400 In-Reply-To: Cc: Claude Pache , ayesh@php.watch, Bilge , php internals To: Stephen Reay References: <88D83E92-94BE-4548-B398-8F5C74765FFD@gmail.com> <882BD9E0-42E9-4C84-A144-7C1DFC4CE5EB@newclarity.net> X-Mailer: Apple Mail (2.3696.120.41.1.8) From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_9A9C983E-5EDF-4965-8ABE-B11D66081208 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Jun 24, 2024, at 11:17 PM, Stephen Reay = wrote: >=20 >=20 >=20 >> On 25 Jun 2024, at 09:22, Mike Schinkel wrote: >>=20 >>> On Jun 24, 2024, at 3:53 AM, Ayesh Karunaratne > wrote: >>> - Why is it a class-level flag and not an attribute (similar to the >>> `#[Override]` attribute in PHP 8.3) ? >>=20 >> =46rom my perspective that would create much confusion among every = PHP developer who has not committed to memory when to use `static` as a = class keyword and when to use it as an attribute. >>=20 >> Given the concept already exists in keywords I would strongly argue = that it makes no sense to introduce as an attributes in core PHP. =20 >>=20 >> Attributes are great for concepts new to PHP, IMO, but not for = existing concepts already part of PHP implemented with keywords. >>=20 >>> On Jun 24, 2024, at 4:27 AM, Claude Pache > wrote: >>> * The main purpose of the `abstract` keyword is to prevent a class = to be instantiated, which (in case of static class) is more semantically = described by the `static` marker. Beyond that, it just allows to declare = a method that, if implemented by a subclass, should have a compatible = signature. Most notably, it does not prevent the other static members of = the class to be used directly. >>=20 >> Given a primary purpose for being able to declare a class `static` is = to signal intent, disallowing `abstract static` classes seems at odds = with that goal. >>=20 >> Of course it is currently true that `static` methods of `abstract` = classes can be called from outside a class and its class hierarchy, so = if we allow declaring `abstract static` classes then it would never in = the future be possible to lock down calls of `static` methods to those = `abstract` classes. >>=20 >> So IMO it would be better to disallow calling `static` methods from = outside a declared `abstract static` class and its inheritance hierarchy = as part of this RFC. That would be backward compatible since there are = currently no classes that are declared in that manner. Doing otherwise = would force those who want to declare a class as both `static` and = `abstract` to have to make a choice rather than being able to signal = their full intent. Which brings us back to the "implied" vs. "explicitly = declared" bifurcation I mentioned in a prior email. >>=20 >> BTW, I am assuming it is technically possible to disallow calling = methods for classes declared both `abstract` and `static` without = considerable difficulty in implementation and without creating a = significant drain on performance.=20 >>=20 >> -Mike=20 >>=20 >> P.S. I would argue the same for `readonly static` properties, but as = that seems those would require an involved discussion about the exact = rules to implement I am demurring on that topic. >=20 > Hi Mike, >=20 >=20 >> So IMO it would be better to disallow calling `static` methods from = outside a declared `abstract static` class >=20 > Can you explain what you mean by this, or more specifically the "why". = What (implied wrong/bad) scenario are you trying to prevent, by = disallowing a static method on an abstract class to be called? >=20 > As you point out, it's already possible to call (public) static = methods on abstract classes, the same as it's possible to call (public) = static methods without instantiating a regular class. >=20 > So why should static abstract classes be different? If the static = method shouldn't be called publicly, it shouldn't be public. Are you = suggesting that public static methods shouldn't be callable on *any* = abstract class? If so, this sounds like a huge BC break, and if not, it = sounds like a confusing "if-then-but-why" scenario. Thank you for the question. I was not specifically advocating `static` methods to be disallowed to = be called on an `abstract` class. I was instead addressing the desire by = another list member to have classes declared `static` not also be able = to be declared `abstract.` That person made the argument that if = 'abstract static` did not actually have any effect then it should not be = allowed by the RFC.=20 What affect are we talking about? If it is both `abstract` and `static` = then it would seem to me the only effect such a declaration could have = would be to disallow the calling of static methods using the named = abstract static class, e.g.: abstract static class Base { static public foo() { echo "foo() called\n" } } static class Concrete extends Base {} Concrete::foo(); // works Base::foo(); // fails My only real argument for disallowing static method calls on abstract = static classes is that if we didn't do so initially we would never be = able to disallow because of BC. In summary, my argument was really only about ensuring we allow = "abstract static" declaration so developers can signal intent and also = to address the objections of the other list member. But if given the = option, I think it would be good to disallow calling static methods on = abstract static classes if only to reserve the right to allow in the = future vs. closing that door immediately. Still, that latter is not the = hill for me to die on. > I agree that the `static` keyword is a much better fit here, however = there is one other aspect here that may come into it (as much as I = prefer the keyword approach): the Attribute approach is backwards = compatible (with a polyfill) to let code using this feature also run on = previous PHP releases. Given that this is mostly intended as a way to = signal intent about a pattern that's already in use, this may be = significant for library authors. Well, as previously stated, I think that would be confusing.=20 Though I do see your reasoning for wanting it to be an attribute. = However... > Personally (as a library author) I don't think that ability is worth = the weirdness of an attribute vs a keyword, but it may be more important = for others who are voting, and I'd rather have the feature with slightly = odd syntax rather than not at all. I too am not convinced that the ongoing confusion would be better than = the temporary need to support older versions of PHP with the same source = file.=20 Given that a build step could address the syntax there are certainly = other new language features that require developers to bifurcate their = libraries to support different versions, why make this one unique? That said, it could be a voting option for the RFC? -Mike --Apple-Mail=_9A9C983E-5EDF-4965-8ABE-B11D66081208 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii
On Jun 24, 2024, at = 11:17 PM, Stephen Reay <php-lists@koalephant.com> wrote:



On 25 = Jun 2024, at 09:22, Mike Schinkel <mike@newclarity.net>= wrote:

On Jun 24, 2024, at 3:53 AM, = Ayesh Karunaratne <ayesh@php.watch> wrote:
- Why is = it a class-level flag and not an attribute (similar to the
`#[Override]` attribute in PHP 8.3) ?

=46rom my = perspective that would create much confusion among every PHP developer = who has not committed to memory when to use `static` as a class keyword = and when to use it as an attribute.

Given the concept already exists in = keywords I would strongly argue that it makes no sense to introduce as = an attributes in core PHP.  

Attributes are great for concepts new = to PHP, IMO, but not for existing concepts already part of PHP = implemented with keywords.

On Jun 24, 2024, at 4:27 AM, Claude Pache = <claude.pache@gmail.com> wrote:
* The main purpose of the `abstract` keyword is to prevent a = class to be instantiated, which (in case of static class) is more = semantically described by the `static` marker. Beyond that, it just = allows to declare a method that, if implemented by a subclass, should = have a compatible signature. Most notably, it does not prevent the other = static members of the class to be used directly.

Given a = primary purpose for being able to declare a class `static` is to signal intent, disallowing `abstract static` classes = seems at odds with that goal.

Of course it is currently true that = `static` methods of `abstract` classes can be called = from outside a  class and its class hierarchy, so if we allow = declaring `abstract static` classes then it would never in the future be = possible to lock down calls of `static` methods to those `abstract` = classes.

So IMO it would be better to = disallow calling `static` methods from outside a declared `abstract = static` class and its inheritance hierarchy as part of this RFC. That = would be backward compatible since there are currently no classes that = are declared in that manner.  Doing otherwise would force those who = want to declare a class as both `static` and `abstract` to have to make = a choice rather than being able to signal their full intent. Which = brings us back to the "implied" vs. "explicitly declared" bifurcation I mentioned in a prior = email.

BTW, I = am assuming it is technically possible to disallow calling methods for = classes declared both `abstract` and `static` without considerable = difficulty in implementation and without creating a significant drain on = performance. 

-Mike 

P.S. I would argue the same for `readonly = static` properties, but as that seems those would require an involved = discussion about the exact rules to implement I am demurring on that = topic.

Hi Mike,


So IMO it = would be better to disallow calling `static` methods from outside a = declared `abstract static` class

Can you explain what you mean by this, or = more specifically the "why". What (implied wrong/bad) scenario are you = trying to prevent, by disallowing a static method on an abstract class = to be called?

As you point out, it's already possible to call (public) = static methods on abstract classes, the same as it's possible to call = (public) static methods without instantiating a regular class.

 So why should = static abstract classes be different? If the static method shouldn't be = called publicly, it shouldn't be public. Are you suggesting that public = static methods shouldn't be callable on *any* abstract class? If so, = this sounds like a huge BC break, and if not, it sounds like a confusing = "if-then-but-why" scenario.

Thank you for the = question.

I was not specifically = advocating `static` methods to be disallowed to be called on an = `abstract` class. I was instead addressing the desire by another list = member to have classes declared `static` not also be able to be declared = `abstract.` That person made the argument that if 'abstract static` did = not actually have any effect then it should not be allowed by the = RFC. 

What affect are we = talking about?  If it is both `abstract` and `static` then it would = seem to me the only effect such a declaration could have would be to = disallow the calling of static methods using the named abstract static = class, e.g.:

abstract static class = Base {
   static public foo() {
  =     echo "foo() called\n"
  =  }
}
static class Concrete extends Base = {}

Concrete::foo();  // works
Base::foo();        // fails

My only real argument = for disallowing static method calls on abstract static classes is that = if we didn't do so initially we would never be able to disallow because = of BC.

In summary, my argument = was really only about ensuring we allow "abstract static" declaration so = developers can signal intent and also to address the objections of the = other list member. But if given the option, I think it would be good to = disallow calling static methods on abstract static classes if only to = reserve the right to allow in the future vs. closing that door = immediately. Still, that latter is not the hill for me to die = on.

I agree that = the `static` keyword is a much better fit here, however there is one = other aspect here that may come into it (as much as I prefer the keyword = approach): the Attribute approach is backwards compatible (with a = polyfill) to let code using this feature also run on previous PHP = releases. Given that this is mostly intended as a way to signal intent = about a pattern that's already in use, this may be significant for = library authors.

Well, = as previously stated, I think that would be = confusing. 

Though I do see = your reasoning for wanting it to be an attribute. = However...

Personally (as a library author) I don't think that ability = is worth the weirdness of an attribute vs a keyword, but it may be more = important for others who are voting, and I'd rather have the feature = with slightly odd syntax rather than not at = all.

I too am not = convinced that the ongoing confusion would be better than the temporary = need to support older versions of PHP with the same source = file. 

Given that a build step = could address the syntax there are certainly other new language features = that require developers to bifurcate their libraries to support = different versions, why make this one unique?

That said, it could be a voting option for the = RFC?

-Mike

= --Apple-Mail=_9A9C983E-5EDF-4965-8ABE-B11D66081208--