Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123788 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 8862A1A009C for ; Mon, 24 Jun 2024 20:18:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719260381; bh=YV9fOnPEqwdalCwyCKbGhAZ80JWwXCsfgaAN2kFQhQA=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=WNLcHLkGie6q2P2I1J+SjAFFCr3wQ78eDY+S+rV0pEoNFcqxG5JSqxIgaon3Az3FH cLWVof8qu+644MkuCL9FmzNleG1BiXYjmdQH74oXIt+cACnT3gPk+uID68Zth9nrJq cJlLQ5KgiSQFchkZl4yClk+liXohJCD6bRNgwWEnzM0o33IW/3XT/bT9JgOIrMYc2J mHp+8DwvcbaKXsEDJmGxYiscZyRSX37dyLzzB15rTZAJroIBFBPfE+yyux6prTE5nE HELB9S3D8+LS5AeBJ7zY9PAgtass4uI0E8QDrA1TsbjldjEQImwn3xv1zDWeNFT7Ax y3O7JGdE6+KpA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 801BA1808E4 for ; Mon, 24 Jun 2024 20:19: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.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_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 mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (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 Jun 2024 20:19:40 +0000 (UTC) Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-364a3d5d901so3387377f8f.0 for ; Mon, 24 Jun 2024 13:18:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scriptfusion-com.20230601.gappssmtp.com; s=20230601; t=1719260302; x=1719865102; darn=lists.php.net; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=U5X5eIWP78NG9T8FLeKlXt/ppzVrvmT+xEn8S+IXOVk=; b=nr9r6F357bVmLEhug+/zEqja96Xejth21DFOtYjtymC0nnyxC8dbMifFKuXso+Fxlf 3LIiKZQnHxiSymufM6TWLlVMcPEPW6nZPbrF/JrSCkhmxn1JC4zFQwgBqZqospwnj6mJ enB7q28Eag3kGmb9wBeMmR0E4Wwog5Pt21/t3COQj7sk5HB4C3I5YqA+4o5Lz4nBSSvg roHcn8JgAShmGzGn9TkyS89TB+TxxEV8wIFJ0Fcm8/ZhNXJuqG5yQD/8+92JzGuzJJzO 5YVGMrddFwkHGFqKVN6GRIaxl+l19Nl2uPWeZ/a7q3P4cP4zcsfTcpMdrB5AU2+JWW1t baKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719260302; x=1719865102; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=U5X5eIWP78NG9T8FLeKlXt/ppzVrvmT+xEn8S+IXOVk=; b=kG+4wNCiqoFQf1xqiVKv28evo2vNl3FELwuO+Bt9YtT21dVjlUyC8dgfNCXGV2KGRi 7MnnxMe+Hq/3ongYFFJfQ+645X8/y3Lk8feYIILSWVGyxA9eJhHDr1lDpi9jnxslMmsQ Fhq1HEe+A6vkMKaWkXAw7iy/tqhwDuyFWobUqVZ69yrceY1JrcrzTx8KGgUCxHXsCmf/ SnRxt0CdDHvGpa8lYB5dhTTyPfm/Ed45BNfkIIhMeoylZapixMmVnbYJksi39wYAL8pC 45OTkvgakMueEPAIcY6t0eqEIY1k8+qaYhz/ntLFfB8Oy4G08R/eWLV2txLBrp+nED64 Yajw== X-Gm-Message-State: AOJu0YxmY9mtiUy5e77Gs3153DVsONQeBrF4e7Pl5mFkD9nxPce1QmHk ibyv8GGdUvXp5QdNYfs7AI9l3KdPf2dclBCwkF76LNam8+HyvTX+TjS4K3MCYRs= X-Google-Smtp-Source: AGHT+IFC/v9NUrdpRdxFkVShPDt2vJtFETCZIJdZfHsY46Q0e/daT4HYwTNTLIdcHXH/n9DNm2hnbQ== X-Received: by 2002:adf:f788:0:b0:362:90cc:6286 with SMTP id ffacd0b85a97d-366e965fec2mr3418581f8f.69.1719260302220; Mon, 24 Jun 2024 13:18:22 -0700 (PDT) Received: from ?IPV6:2a01:4b00:bf09:5101:7168:677:94f9:b75d? ([2a01:4b00:bf09:5101:7168:677:94f9:b75d]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-3663a8c8f07sm11045579f8f.110.2024.06.24.13.18.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 24 Jun 2024 13:18:21 -0700 (PDT) Content-Type: multipart/alternative; boundary="------------uSFDEN5L4mPn8GrEfVFu0Koa" Message-ID: <501a6892-377b-4156-a18e-a9b3eb33d629@scriptfusion.com> Date: Mon, 24 Jun 2024 21:18:20 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [RFC] Static class To: Claude Pache Cc: php internals References: <88D83E92-94BE-4548-B398-8F5C74765FFD@gmail.com> Content-Language: en-GB In-Reply-To: <88D83E92-94BE-4548-B398-8F5C74765FFD@gmail.com> From: bilge@scriptfusion.com (Bilge) This is a multi-part message in MIME format. --------------uSFDEN5L4mPn8GrEfVFu0Koa Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 24/06/2024 09:27, Claude Pache wrote: > Hi, Hi Claude! I really appreciate your feedback. Everything you highlighted is an important point that will be included in the RFC! > A general remark: I appreciate that a static class does not impose arbitrary restrictions (like: implicitly `final`) on the class beyond what is meaningful for staticness. On the other side, I don’t think that we should support markers that are technically possible, but semantically meaningless, like the `readonly` marker on class. Great point, `readonly` and `static` should be mutually exclusive and generate a compile-time error, since `readonly static` properties are not supported. > Some more specific remarks: > > * In the intro: “A static class is a class whose members (properties and methods) are all static”. One of the most important point is missing, namely: It is meaningless for a static class to have instances. I thought that was covered off, but I'll see if I can word it better. > * In the “Proposal” section, it should be stated explicitly that any attempt to construct an instance, not only with `new`, but also with any of the `ReflectionClass::newInstance*()` methods, or with `unserialize()`, or with whatever other mean, shall fail. Great point, I'll include that detail.I think we're also missing a similar detail with respect to dynamic properties, which should of course also be forbidden. > Should a static class be marked `readonly` or `abstract`? I think not, because those have no real semantic meaning for static class; their effects on static members are only consequences of their intended meaning on non-static class: > > * Unless/until the `readonly` marker may be applied to static properties, the only effect of such a keyword, is that it would prevent the creation of static properties. I don’t know if that restriction is useful, but in case it would be used for that purpose, it would be hijacking the `readonly` marker for a something it wasn’t intended for. Agree, as above, we'll make them mutually exclusive. > * 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. I tend to find inheritance is not a very useful concept in static contexts, but others have already pointed out that some have found uses for it. Due to my lack of experience I cannot confidently say that `abstract static` has no value, but you make a compelling argument. Happy to add a similar mutual exclusivity prohibition for this keyword too, unless and until someone protests it with an equally compelling argument to the contrary. > The RFC says that a static class may extend a class not explicitly marked as static, but with no instance member. This is not sound, because a class with no instance members is not necessarily static. The most obvious example is `stdClass` (which has no member at all, even if their instances may have properties). Do you mean it is not simply sufficient for a class to be regarded as implicitly static by virtue of the fact that it has no instance members? I'm not sure I agree, but I may be missing something. If we extend `stdClass` then we gain nothing, and our class so extending it can still be safely marked static, can it not? Please elaborate so I might understand better. Kind regards, Bilge --------------uSFDEN5L4mPn8GrEfVFu0Koa Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 24/06/2024 09:27, Claude Pache wrote:
Hi,
Hi Claude! I really appreciate your feedback. Everything you highlighted is an important point that will be included in the RFC!
A general remark: I appreciate that a static class does not impose arbitrary restrictions (like: implicitly `final`) on the class beyond what is meaningful for staticness. On the other side, I don’t think that we should support markers that are technically possible, but semantically meaningless, like the `readonly` marker on class.
Great point, `readonly` and `static` should be mutually exclusive and generate a compile-time error, since `readonly static` properties are not supported.
Some more specific remarks:

* In the intro: “A static class is a class whose members (properties and methods) are all static”. One of the most important point is missing, namely: It is meaningless for a static class to have instances.
I thought that was covered off, but I'll see if I can word it better.
* In the “Proposal” section, it should be stated explicitly that any attempt to construct an instance, not only with `new`, but also with any of the `ReflectionClass::newInstance*()` methods, or with `unserialize()`, or with whatever other mean, shall fail.
Great point, I'll include that detail. I think we're also missing a similar detail with respect to dynamic properties, which should of course also be forbidden.
Should a static class be marked `readonly` or `abstract`? I think not, because those have no real semantic meaning for static class; their effects on static members are only consequences of their intended meaning on non-static class:

* Unless/until the `readonly` marker may be applied to static properties, the only effect of such a keyword, is that it would prevent the creation of static properties. I don’t know if that restriction is useful, but in case it would be used for that purpose, it would be hijacking the `readonly` marker for a something it wasn’t intended for.
Agree, as above, we'll make them mutually exclusive.
* 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.
I tend to find inheritance is not a very useful concept in static contexts, but others have already pointed out that some have found uses for it. Due to my lack of experience I cannot confidently say that `abstract static` has no value, but you make a compelling argument. Happy to add a similar mutual exclusivity prohibition for this keyword too, unless and until someone protests it with an equally compelling argument to the contrary.
The RFC says that a static class may extend a class not explicitly marked as static, but with no instance member. This is not sound, because a class with no instance members is not necessarily static. The most obvious example is `stdClass` (which has no member at all, even if their instances may have properties).

Do you mean it is not simply sufficient for a class to be regarded as implicitly static by virtue of the fact that it has no instance members? I'm not sure I agree, but I may be missing something. If we extend `stdClass` then we gain nothing, and our class so extending it can still be safely marked static, can it not? Please elaborate so I might understand better.

Kind regards,
Bilge

--------------uSFDEN5L4mPn8GrEfVFu0Koa--