Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125574 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 3323E1A00BD for ; Tue, 17 Sep 2024 04:35:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1726547882; bh=V1bjMaSdFgqBPog8Pnz5Qz4Qdig30t6M+l+KD52fbb8=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=m3QmiB6H4Dub1jdxnIqQvwRkbRiijBlwf4I+kxte7vlNLU1EnE7LHLO+UqutWrAYe q3/nEtN4HdKUE+ILrOFpSYIEzIGalUFYC6BsYjm8g1PBVAMZX9qbJc+tiHxW6XSntq bOaGUHd2BupioFSCoyyEj4KWjzQdj+zcgeYd4dUkIGeUzApdj8XaX75MkxBYr4yZ0T 8pAFQO3bsg4bdLt5HpC7yekB2cmnmg0m5RqKRHA+JN8o+BO+9CDl8uXYDufRkX6zaY c6zs2KXv1W2vS9df1BfDek/mlYqizxIFDgievdu7gLKg2ub4r5KjdVLMmUCEEeao9w FIVHQqrfHwGEg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 86804180052 for ; Tue, 17 Sep 2024 04:38:01 +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 autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-yw1-f173.google.com (mail-yw1-f173.google.com [209.85.128.173]) (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 ; Tue, 17 Sep 2024 04:38:01 +0000 (UTC) Received: by mail-yw1-f173.google.com with SMTP id 00721157ae682-6d5893cd721so30454527b3.0 for ; Mon, 16 Sep 2024 21:35:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1726547755; x=1727152555; 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=UIiYW7fsJc27QCEWdZI12dguCtNYr+U+m+8oVJ5El4g=; b=JQiBa8RKSQO8uKR/joCAGwfg2l6eArs6kmXjcmnpXhCWxsjF3SBP1ZD7ofcBoFtmpf fHSOPs3MOU3eglgo9cPdXWYabXfmRLT7gG5Wq965CbfrVmyRPpCc1F7Ub4nEh1ZDY+Tu cxUbyHtVXTiXPPYiGImIZl0KBCCXzN2FPMieBNS6g2mh3bIPBJ+NLbkyfGTgO0M/j6xA G/OdNWiNRd7gPh85yPXaDUd0qOdwjoS9rl4A4LmFMk2HvG9wAwvmGGoB/pZOjhplHP8d v8ko6+aDPN4qlrpuDCLXFqw/w9nbLoJJH0XQ42ZHf6gJ2xv/hha3Szxju/Plym6uLsbZ /Qog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726547755; x=1727152555; 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=UIiYW7fsJc27QCEWdZI12dguCtNYr+U+m+8oVJ5El4g=; b=julTMdhFBQRHFusWH5UtANm/2SBMUnmh29yjd/2D8w9ARJWtH33w6KhZYRjrtiBV9V 4l7WcipcQh+mM/IN+jExb6Xg+m+zvkFKYknPvjCyZXfbci6GrR5AcqeCRuU+fkpWBaFN 3LPaXyHYpn30lVNz0wprmdnTP5okfx77qRbkd/HGLsred85eolPbsPzjHN4GL/iGXHjO +3uY1WZqYzB7Kl6w5nPjjh72SgLRM9yvpsrq5mD9daqVcL4/Hq9efVfJIMbfsHRK2UmN dBB0mejb+6fnI3Tok4SXfbI8B7qzTjEjPuKBuiH4vwx6AFMVqid+mAdmNZ/IFE7B5JsH OCqg== X-Gm-Message-State: AOJu0YwbVTb3mkzeLQ24hGvhbglTd/WkS/rlNx654hV+Atzl6P9P3Vbq XLvmnPl/o6Q1wJWnDUF2iJzhd0A8x1Ez4aj5Bt1qnGVv9+aAlPJMkbIBCewBLOCZAefUCK9e06H g X-Google-Smtp-Source: AGHT+IFnXQSomKPtmAAO2E26Jb6Uw/tuYd9SH1jKOb7HFBptjI5KBzWTpnXbupWHrArykjMkhGQVZg== X-Received: by 2002:a05:690c:688b:b0:6dd:bcfd:f168 with SMTP id 00721157ae682-6ddbcfdf292mr53928587b3.18.1726547755116; Mon, 16 Sep 2024 21:35:55 -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 00721157ae682-6dbe2ed0027sm11997607b3.84.2024.09.16.21.35.50 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Sep 2024 21:35:54 -0700 (PDT) Message-ID: <18603813-9ECB-4486-95EE-08BEDECAB88D@newclarity.net> Content-Type: multipart/alternative; boundary="Apple-Mail=_A3020472-964B-42C6-9F54-8A3B3C43D35B" Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.10\)) Subject: Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again) Date: Tue, 17 Sep 2024 00:35:49 -0400 In-Reply-To: Cc: PHP internals To: Jordan LeDoux References: X-Mailer: Apple Mail (2.3696.120.41.1.10) From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_A3020472-964B-42C6-9F54-8A3B3C43D35B Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Sep 14, 2024, at 5:48 PM, Jordan LeDoux = wrote: >=20 > Hello internals, >=20 > This discussion will use my previous RFC as the starting point for = conversation: https://wiki.php.net/rfc/user_defined_operator_overloads >=20 > There has been discussion on list recently about revisiting the topic = of operator overloads after the previous effort which I proposed was = declined. There are a variety of reasons, I think, this is being = discussed, both on list and off list. >=20 > 1. As time has gone on, more people have come forward with use cases. = Often they are use cases that have been mentioned before, but it has = become more clear that these use cases are more common than was = suggested previously. > 2. Several voters, contributors, and participants have had more time = (years now) to investigate and research some of the related issues, = which naturally leads to changes in opinion or perspective. > 3. PHP has considered and been receptive toward several RFCs since my = original proposal which update the style of PHP in ways which are = congruent with the KIND of language that has operator overloads. >=20 > I mentioned recently that I would not participate in another operator = overload RFC unless I felt that the views of internals had become more = receptive to the topic, and after some discussion with several people = off-list, I feel that it is at least worth discussing for the next = version. >=20 > Operator overloads has come up as a missing feature in several = discussions on list since the previous proposal was declined. This = includes: >=20 > [RFC] [Discussion] Support object type in BCMath [1] > Native decimal scalar support and object types in BcMath [2] > Custom object equality [3] > pipes, scalar objects and on? [4] > [RFC][Discussion] Object can be declared falsifiable [5] >=20 > The request to support comparison operators (>, >=3D, =3D=3D, !=3D, = <=3D, <, <=3D>) has come up more frequently, but particularly in = discussion around linear algebra, arbitrary precision mathematics, and = dimensional numbers (such as currency or time), the rest of the = operators have also come up. >=20 > Typically, these use cases are themselves very niche, but the = capabilities operator overloads enable would be much more widely used. = =46rom discussion on list, it seems likely that very few libraries would = need to implement operator overloads, but the libraries that do would be = well used and thus MANY devs would be consumers of operator overloads. >=20 > I want to discuss what changes to the previous proposal people would = be seeking, and why. The most contentious design choice of the previous = proposal was undoubtedly the `operator` keyword and the decision to make = operator overload implementations distinct from normal magic methods. = For some of the voters who voted yes on the previous RFC, this was a = "killer feature" of the proposal, while for some of the voters who voted = no it was the primary reason they were against the feature. >=20 > There are also several technical and tangentially related items that = are being worked on that would be necessary for operator overloads (and = were originally included in my implementation of the previous RFC). This = includes: >=20 > 1. Adding a new opcode for LARGER and LARGER_OR_EQUAL so that operand = position can be preserved during ALL comparisons. > 2. Updating ZEND_UNCOMPARABLE such that it has a value other than -1, = 0, or 1 which are typically reserved during an ordering comparison. > 3. Allowing values to be equatable without also being orderable (such = as with matrices, or complex numbers). >=20 > These changes could and should be provided independent of operator = overloads. Gina has been working on a separate RFC which would cover all = three of these issues. You can view the work-in-progress on that RFC = here: = https://github.com/Girgias/php-rfcs/blob/master/comparison-equality-semant= ics.md >=20 > I hope to start off this discussion productively and work towards = improving the previous proposal into something that voters are willing = to pass. To do that, I think these are the things that need to be = discussed in this thread: Anyone who just happened to see my prior messages on the topic know that = I have strongly advocated against operator overloads. Rather than repeat my full arguments on the list, I will instead = summarize by linking to three (3) of the comments from Jordan's Reddit = poll, two of them mine. If you *only* read one of them, read the *last* = one: - https://www.reddit.com/r/PHP/comments/rv11fc/comment/hr2ujix/ = - https://www.reddit.com/r/PHP/comments/rv11fc/comment/lnha4gq/ = - https://www.reddit.com/r/PHP/comments/rv11fc/comment/lnhcbqr/ = Basically my concerns are that operator overloading has benefits for a = subset of developers that are certainly in the minority =E2=80=94 = developers using PHP for math, scientific and similar fields =E2=80=94 = and yet it would place a burden on everyone. That is why I have been = against it. HOWEVER, today I identified an approach that would allow me support = operator overloading and that is to reduce the scope in which the use of = operator overloads are valid.=20 But let me answer the questions before I elaborate. > 1. Should the next version of this RFC use the `operator` keyword, or = should that approach be abandoned for something more familiar? Why do = you feel that way? I have no strong opinion on using `operator`, pro or con OTOH I would prefer that operators are spelled out vs. just the sigil, = e.g. `add` and `minus` vs. `+` and `-`. They would be easier and quicker = for refactoring IDEs to find them with fewer false positives, especially = in text vs code, and they would be easier to "see" when scanning source = code. =20 That said, this is not a hill I want to die on so I am just registering = my opinion and then will move on. > 2. Should the capability to overload comparison operators be provided = in the same RFC, or would it be better to separate that into its own = RFC? Why do you feel that way? I have no strong opinion on this. > 3. Do you feel there were any glaring design weaknesses in the = previous RFC that should be addressed before it is re-proposed? Yes, the fact that there were no constraints of the nature I propose = below. > 4. Do you feel that there is ANY design, version, or implementation of = operator overloads possible that you would support and be in favor of, = regardless of whether it matches the approach taken previously? If so, = can you describe any of the core ideas you feel are most important? Yes, if constraints of the nature I propose below are adopted. The biggest problem I have with operator overloads is that =E2=80=94 = once added =E2=80=94 all code could potentially be "infected" with = operator overloads. However, if the developer *using* an operator = overload could instead opt-in to using them, in context, then I would = flip my opinion and I would begin to support them. =20 What might opt-in look like? I propose two (2) mechanisms of which each = would be useful for different use-cases. As such I do not see these two = as competing but instead would expect adding both to be preferable: 1. Add a pair of sigils to enclose any expression that would need to = support userland operator overloading. This would allow a developer to = isolate just the expression that needs to use operator overloading. I = propose {[...]} for this, but feel free to bikeshed sigils. Using an = example from the RFC, here is what code might look like: $cnum1 =3D new ComplexNumber(1, 2); $cnum2 =3D new ComplexNumber(3, 4); $cnum3 =3D {[ $cnum1 * $cnum2 ]}; // Uses operator = operloading sigils echo $cnum3->realPart.' + '.$cnum3->imaginaryPart.'i'; 2. For when using `{[...]}` would be annoying because it would be needed = in so many places, PHP could also add support for an attribute. e.g. = `#[OperatorOverloads(Userland:true)]`. This attribute would apply to = functions, methods, classes, enums, (other?) and indicates that operator = overloads can be present anywhere in the body of the decorated = structure. I included `Userland:true` as an indicator to a reader that = this only applies to userland operator overloads and that built-in ones = like in GMP and anywhere else would not need to be opted into, but that = parameter could of course be dropped if others feel it is not needed. = Again, feel free to bikeshed attribute name and/or parameters. #[OperatorOverloads(Userland:true)] function SprintProductOfTwoComplex(ComplexNumber $cnum1, ComplexNumber = $cnum2)string { $cnum3 =3D $cnum1 * $cnum2; return sprintf("%d + %di", $cnum3->realPart, $cnum3->imaginaryPart); } If this approach were included in the RFC then it would also ensure = there is no possibility of BC breakage. BC breakage which would = certainly be an edge case but I can envision it would be possible,e = specially where newer instances incorporating operator overloads are = passed to functions that did not have parameters type hinted but were = not intend to be used with operator overloads resulting in subtle = potential breakage.=20 This argument is also consistent with the argument people had about not = allowing default values to be generically used in calls to the function = function. Their claim was that developers who did not write their code = with the intention of exposing defaults should not have their defaults = exposed. Similarly developers that do not write their code to enable = operator overloads should not be used with userland operator overloads = unless they explicitly allow it, especially as they may not have have = tested code with operator overloads. Anyway, that is my two cents worth.=20 TL;DR? I argue that PHP should operator overloads but ONLY if there is = a mechanism that requires the user of expressions that call overloaded = operators to explicitly opt-in to their use. -Mike --Apple-Mail=_A3020472-964B-42C6-9F54-8A3B3C43D35B Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8

On = Sep 14, 2024, at 5:48 PM, Jordan LeDoux <jordan.ledoux@gmail.com> wrote:

Hello internals,

This discussion = will use my previous RFC as the starting point for conversation: https://wiki.php.net/rfc/user_defined_operator_overloads
There has been discussion on list recently = about revisiting the topic of operator overloads after the previous = effort which I proposed was declined. There are a variety of reasons, I = think, this is being discussed, both on list and off list.

1. As time has gone on, more people have come = forward with use cases. Often they are use cases that have been = mentioned before, but it has become more clear that these use cases are = more common than was suggested previously.
2. Several = voters, contributors, and participants have had more time (years now) to = investigate and research some of the related issues, which naturally = leads to changes in opinion or perspective.
3. PHP has = considered and been receptive toward several RFCs since my original = proposal which update the style of PHP in ways which are congruent with = the KIND of language that has operator overloads.

I mentioned recently that I would not participate in another = operator overload RFC unless I felt that the views of internals had = become more receptive to the topic, and after some discussion with = several people off-list, I feel that it is at least worth discussing for = the next version.

Operator overloads has = come up as a missing feature in several discussions on list since the = previous proposal was declined. This includes:

[RFC] [Discussion] Support object type in BCMath [1]
Native decimal scalar support and object types in BcMath = [2]
Custom object equality [3]
pipes, scalar = objects and on? [4]
[RFC][Discussion] Object can be = declared falsifiable [5]

The request to = support comparison operators (>, >=3D, =3D=3D, !=3D, <=3D, = <, <=3D>) has come up more frequently, but particularly in = discussion around linear algebra, arbitrary precision mathematics, and = dimensional numbers (such as currency or time), the rest of the = operators have also come up.

Typically, = these use cases are themselves very niche, but the capabilities operator = overloads enable would be much more widely used. =46rom discussion on = list, it seems likely that very few libraries would need to implement = operator overloads, but the libraries that do would be well used and = thus MANY devs would be consumers of operator overloads.
I want to discuss what changes to the previous proposal = people would be seeking, and why. The most contentious design choice of = the previous proposal was undoubtedly the `operator` keyword and the = decision to make operator overload implementations distinct from normal = magic methods. For some of the voters who voted yes on the previous RFC, = this was a "killer feature" of the proposal, while for some of the = voters who voted no it was the primary reason they were against the = feature.

There are also several technical = and tangentially related items that are being worked on that would be = necessary for operator overloads (and were originally included in my = implementation of the previous RFC). This includes:

1. Adding a new opcode for LARGER and LARGER_OR_EQUAL so that = operand position can be preserved during ALL comparisons.
2.= Updating ZEND_UNCOMPARABLE such that it has a value other than -1, 0, = or 1 which are typically reserved during an ordering comparison.
3. Allowing values to be equatable without also being = orderable (such as with matrices, or complex numbers).

These changes could and should be provided independent of = operator overloads. Gina has been working on a separate RFC which would = cover all three of these issues. You can view the work-in-progress on = that RFC here: https://github.com/Girgias/php-rfcs/blob/master/comparison-equa= lity-semantics.md

I hope to start off = this discussion productively and work towards improving the previous = proposal into something that voters are willing to pass. To do that, I = think these are the things that need to be discussed in this thread:

Anyone who just happened to see my prior messages on the = topic know that I have strongly advocated against operator = overloads.

Rather than = repeat my full arguments on the list, I will instead = summarize by linking to three (3) of the comments from Jordan's Reddit = poll, two of them mine.  If you *only* read one of them, read the = *last* one:

- https://www.reddit.com/r/PHP/comments/rv11fc/comment/hr2ujix/
- 
https://www.reddit.com/r/PHP/comments/rv11fc/comment/lnha4gq/
- 
https://www.reddit.com/r/PHP/comments/rv11fc/comment/lnhcbqr/

Basically my = concerns are that operator overloading has benefits for a subset of = developers that are certainly in the minority =E2=80=94 developers using = PHP for math, scientific and similar fields =E2=80=94 and yet it would = place a burden on everyone. That is why I have been against = it.

HOWEVER, = today I identified an approach that would allow me support operator = overloading and that is to reduce the scope in which the use of operator = overloads are valid. 

But let me answer the questions = before I elaborate.

1. Should the next version of this = RFC use the `operator` keyword, or should that approach be abandoned for = something more familiar? Why do you feel that way?

I have no strong opinion on using `operator`, pro or = con

OTOH I would = prefer that operators are spelled out vs. just the sigil, e.g. `add` and = `minus` vs. `+` and `-`. They would be easier and quicker for = refactoring IDEs to find them with fewer false positives, especially in = text  vs code, and they would be easier to "see" when scanning = source code.  

That said, this is not a hill I want to die on so I am just = registering my opinion and then will move on.

2. = Should the capability to overload comparison operators be provided in = the same RFC, or would it be better to separate that into its own RFC? = Why do you feel that way?

I have no strong opinion on = this.

3. Do = you feel there were any glaring design weaknesses in the previous RFC = that should be addressed before it is re-proposed?

Yes, the fact that there were no constraints of the nature I = propose below.

4. Do you feel that there is ANY = design, version, or implementation of operator overloads possible that = you would support and be in favor of, regardless of whether it matches = the approach taken previously? If so, can you describe any of the core = ideas you feel are most important?

Yes, if constraints of the = nature I propose below are adopted.

The biggest problem I have with operator overloads is that = =E2=80=94 once added =E2=80=94 all code could potentially be "infected" = with operator overloads. However, if the developer *using* an operator = overload could instead opt-in to using them, in context, then I would = flip my opinion and I would begin to support them.  

What might opt-in look like? =  I propose two (2) mechanisms of which each would be useful for = different use-cases. As such I do not see these two as competing but = instead would expect adding both to be preferable:

1. Add a pair of sigils to = enclose any expression that would need to support userland operator = overloading. This would allow a developer to isolate just the expression = that needs to use operator overloading. I propose {[...]} for this, but = feel free to bikeshed sigils. Using an example from the RFC, here is = what code might look like:

$cnum1 =3D new ComplexNumber(1, 2);
$cnum2 =3D new ComplexNumber(3, = 4);
$cnum3 =3D {[ = $cnum1 * $cnum2 ]}; =             &n= bsp; // Uses operator operloading sigils
echo $cnum3->realPart.' + = '.$cnum3->imaginaryPart.'i';

2. For when using `{[...]}` would be annoying because it = would be needed in so many places, PHP could also add support for an = attribute. e.g. `#[OperatorOverloads(Userland:true)]`. This attribute = would apply to functions, methods, classes, enums, (other?) and = indicates that operator overloads can be present anywhere in the body of = the decorated structure. I included `Userland:true` as an indicator to a = reader that this only applies to userland operator overloads and that = built-in ones like in GMP and anywhere else would not need to be opted = into, but that parameter could of course be dropped if others feel it is = not needed. Again, feel free to bikeshed attribute name and/or = parameters.

#[OperatorOverloads(Userland:true)]
function = SprintProductOfTwoComplex(ComplexNumber $cnum1, ComplexNumber = $cnum2)string {
  $cnum3 =3D $cnum1 * $cnum2;
  return sprintf("%d + = %di", $cnum3->realPart, $cnum3->imaginaryPart);
}

If this approach were included in the RFC then it would also = ensure there is no possibility of BC breakage. BC breakage which would = certainly be an edge case but I can envision it would be possible,e = specially where newer instances incorporating operator overloads are = passed to functions that did not have parameters type hinted but were = not intend to be used with operator overloads resulting in subtle = potential breakage. 

This argument is also consistent = with the argument people had about not allowing default values to be = generically used in calls to the function function. Their claim was that = developers who did not write their code with the intention of exposing = defaults should not have their defaults exposed. Similarly developers = that do not write their code to enable operator overloads should not be = used with  userland operator overloads unless they explicitly allow = it, especially as they may not have have tested code with operator = overloads.

Anyway, that = is my two cents worth. 

TL;DR?  I argue that PHP = should operator overloads but ONLY if there is a mechanism that requires = the user of expressions that call overloaded operators to explicitly = opt-in to their use.

-Mike

= --Apple-Mail=_A3020472-964B-42C6-9F54-8A3B3C43D35B--