Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125218 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 DBB981A00EA for ; Sun, 25 Aug 2024 15:31:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1724600031; bh=zBmOEfi1Om1XuZLNArdP2oO+xF/CXN5LSyEnR22PoO8=; h=Date:Subject:To:References:From:In-Reply-To:From; b=LHoCKz2iBQsyVjqwCCb1xHGX6QdXb21cDavihnZm87O7qHFFKTf63nKEBShqU+yBt p610D8HzgxoaEfnjDyMuWOtQm4aMBV1OyOE67fUAesKRhPoSe7ZoMlMRtSfgchvH+x iRs5lY8PlhmooGnaeIGoww7jN3B8ykziae2qxnMq5CTwWwtfoHK6kZp7L3BHLz6Vpy rFXOvLc4O7S07CTAssxk1LN37uNvg437xpLNm5zNSFHhMIT3/OuYQmdcOouwKG4aUl syVWTsx78ngO3414yifYmJKCR3DjXaWT9tDautshIJDswF5pE/sjD6IGmvs0Ehf928 zmtbNYsulrXlQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id F2A35180080 for ; Sun, 25 Aug 2024 15:33:48 +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.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fhigh4-smtp.messagingengine.com (fhigh4-smtp.messagingengine.com [103.168.172.155]) (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, 25 Aug 2024 15:33:44 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.nyi.internal [10.202.2.44]) by mailfhigh.nyi.internal (Postfix) with ESMTP id 542661147EEC for ; Sun, 25 Aug 2024 11:31:52 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-04.internal (MEProxy); Sun, 25 Aug 2024 11:31:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; 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=fm1; t=1724599912; x=1724686312; bh=02BVJC2i0w jN2KMwYb6qy6MS3p01Y3hhJZPwvqjJ614=; b=bM1lN+qNzRHrGnugnPSDmFvHYc CnJERSLzk3gRo4QpD+tprCRKO0QRN9RvYVKvOVV95QSZfHYS3fHQt5zSHHxCWVFn OmA7QHBkZpmNbxM89Q8wTpvs2QKVqwLUoYmhFtOFAhUZGVXUYhqe8eg5VSJgBSmj c92pHy38Mnfdk4t+b5xUYyg4j4J9d1Q3jng/Md9wZfpbQUf6YWGTe46Gsd8vwm7P l+67jSvzqIbIha5iKYIhmLHIdi4xB0+0WAcmX67YlUQriK2WDnY8fjYARLw7bea+ ht5HheQbt0q8qUTYV2HNdXdZFng9+V0tS8ImWMR8qcooQcgS4NPs4g3X/Stg== 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=1724599912; x=1724686312; bh=02BVJC2i0wjN2KMwYb6qy6MS3p01 Y3hhJZPwvqjJ614=; b=Js7BKqhQfW/5MITvxalXegogKRo07i7MJvZqbBpy42DN q6ajqCFgePXql6VYXlS9vTX7zQBuplMlO/s0yIGY+ogtW6jwXLObBuOLBkxWk/2F Zp8XFdQQLSRB/RUwWyKrjPt/6gyNPuIqS2LEujjgklEU7v3CozBbX5Yob/4XMWof lXeVFE+jOdSrtEyLs43jRjkvExxemUrotkC5U6C+vr2bNpoxzod7gasOHjOSQnFV XN3gWWgwXoNUuIQhwr60AMt+c0fjoTokv/rIZc1uX7Lvy87GZBEtjX+cBfT4ysy2 deWjheOCDE0TIGfq7OZ4mMSnZpIxVKUs+RmCKXhXZA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddruddviedgkeekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpegtkfffgg gfuffvfhfhjgesrgdtreertddvjeenucfhrhhomhepfdftohifrghnucfvohhmmhhinhhs ucglkffoufhorfgnfdcuoehimhhsohhprdhphhhpsehrfigvtgdrtghordhukheqnecugg ftrfgrthhtvghrnhepheetleeiiefgueduieeuieffvdevheduueefkeejuefgffeftdei tdegtedtleetnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrh homhepihhmshhophdrphhhphesrhifvggtrdgtohdruhhkpdhnsggprhgtphhtthhopedu pdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsth hsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Sun, 25 Aug 2024 11:31:51 -0400 (EDT) Content-Type: multipart/alternative; boundary="------------UEfVf3EgVoeaKqkAax1gWkvA" Message-ID: Date: Sun, 25 Aug 2024 16:31:46 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [RFC] Default expression To: internals@lists.php.net References: <0c8ed5d6-5507-4c41-8d7f-05d14ba8aa4c@scriptfusion.com> <0cfd3a28-3cb0-4478-85fb-cf086d8e5c66@app.fastmail.com> Content-Language: en-GB In-Reply-To: <0cfd3a28-3cb0-4478-85fb-cf086d8e5c66@app.fastmail.com> From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") This is a multi-part message in MIME format. --------------UEfVf3EgVoeaKqkAax1gWkvA Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 25/08/2024 14:35, Larry Garfield wrote: > My other concern is the list of supported expression types. I > understand how the implementation would naturally make all of those > syntactically valid, but it seems many of them, if not most, are > semantically nonsensical. I tend to agree with Larry and John that the list of operators should be restricted - we can always allow more in future, but restricting later is much harder. A few rules that seem logical to me: 1) The expression should be reasonably guaranteed to produce the same type as the actual default. - No casts - No comparison operators, because they produce booleans from non-boolean input - No "<=>". Technically, it has an integer result, but it's rare to use it as one, rather than a kind of three-value boolean - No "instanceof" - No "empty" 2) The expression should not have side effects (outside of exotic operator overloads). - No "include", "require", etc - No "throw" - No "print" - Borderline, but I would also say no "clone" 3) The expression should be passing additional information into the function, not pulling information out of it. The syntax shouldn't be a way to write obfuscated reflection, or invert data flow from callee to caller. - No assignments. - No ternaries with "default" on the left-hand side - "$foo ? $bar : default" is acting on local knowledge, but "default ? $foo : $bar" is acting on information the caller shouldn't know - Same for "?:" and "??" - No "match" with "default" as the condition or branch, for the same reason. "match($foo) { $bar => default }" is fine, match(default) { ... }" or "match($foo) { default => ... }" are not. Note that these can be seen as aspects of the same rule: the aim of the expression should be to transform the default value into another value of the same type, not to pull it out and perform arbitrary operations based on it. I believe that leaves us with: - Arithmetic operators: binary + - * / % **, unary + - - Bitwise operators: & | ^ << >>  ~ - Boolean operators: && || and or xor ! - Conditions with default on the RHS: $foo ? $bar : default, $foo ?: default, $foo ?? default, match($foo) { $bar => default } - Parentheses: (((default))) Even then, I look at that list and see more problems than use cases. As the RFC points out, library authors already worry about the maintenance burden of named argument support, will they now also need to question whether someone is relying on "default + 1" having some specific effect? Maybe we should instead require justification for each addition: - Bitwise | is nicely demonstrated in the RFC - Bitwise & could probably be justified on similar grounds - "$foo ? $bar : default" is discussed in the RFC - The other "conditions with default on the RHS" in my shortlist above fit the same basic use case Beyond that, I'm struggling to think of meaningful uses: "whatever the function sets as its default, do the opposite"; "whatever number the function sets as default, raise it to the power of 3"; etc. Again, they can easily be added in later versions, if a use case is pointed out. Regards, -- Rowan Tommins [IMSoP] --------------UEfVf3EgVoeaKqkAax1gWkvA Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 25/08/2024 14:35, Larry Garfield wrote:
My other concern is the list of supported expression types.  I 
understand how the implementation would naturally make all of those 
syntactically valid, but it seems many of them, if not most, are 
semantically nonsensical.


I tend to agree with Larry and John that the list of operators should be restricted - we can always allow more in future, but restricting later is much harder.

A few rules that seem logical to me:

1) The expression should be reasonably guaranteed to produce the same type as the actual default.

- No casts
- No comparison operators, because they produce booleans from non-boolean input
- No "<=>". Technically, it has an integer result, but it's rare to use it as one, rather than a kind of three-value boolean
- No "instanceof"
- No "empty"

2) The expression should not have side effects (outside of exotic operator overloads).

- No "include", "require", etc
- No "throw"
- No "print"
- Borderline, but I would also say no "clone"

3) The expression should be passing additional information into the function, not pulling information out of it. The syntax shouldn't be a way to write obfuscated reflection, or invert data flow from callee to caller.

- No assignments.
- No ternaries with "default" on the left-hand side - "$foo ? $bar : default" is acting on local knowledge, but "default ? $foo : $bar" is acting on information the caller shouldn't know
- Same for "?:" and "??"
- No "match" with "default" as the condition or branch, for the same reason. "match($foo) { $bar => default }" is fine, match(default) { ... }" or "match($foo) { default => ... }" are not.

Note that these can be seen as aspects of the same rule: the aim of the expression should be to transform the default value into another value of the same type, not to pull it out and perform arbitrary operations based on it.


I believe that leaves us with:

- Arithmetic operators: binary + - * / % **, unary + -
- Bitwise operators: & | ^ << >>  ~
- Boolean operators: && || and or xor !
- Conditions with default on the RHS: $foo ? $bar : default, $foo ?: default, $foo ?? default, match($foo) { $bar => default }
- Parentheses: (((default)))


Even then, I look at that list and see more problems than use cases. As the RFC points out, library authors already worry about the maintenance burden of named argument support, will they now also need to question whether someone is relying on "default + 1" having some specific effect?

Maybe we should instead require justification for each addition:

- Bitwise | is nicely demonstrated in the RFC
- Bitwise & could probably be justified on similar grounds
- "$foo ? $bar : default" is discussed in the RFC
- The other "conditions with default on the RHS" in my shortlist above fit the same basic use case

Beyond that, I'm struggling to think of meaningful uses: "whatever the function sets as its default, do the opposite"; "whatever number the function sets as default, raise it to the power of 3"; etc. Again, they can easily be added in later versions, if a use case is pointed out.


Regards,

-- 
Rowan Tommins
[IMSoP]
--------------UEfVf3EgVoeaKqkAax1gWkvA--