Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125591 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 7F65C1A00BD for ; Tue, 17 Sep 2024 17:22:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1726593880; bh=lizq4FluZvTq52BFTGE26G4ytkKVR6R0IGgXYvtge5A=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=aYiuyVEIoMId77A7U7phhzo7C/S5JVdhmV7qSGT0Rsjy7/kzCli4dLNyE4lFoM+xo Y4sjh4UfhLl1AUez8/8x50dlZcXPIbQk8fTk4H4zLCxRYO2eVSDSOiT6wNLJ+6pUHr kf7WsVXcAHqeyZCpH/g/LD/XiI/uIdiFNbZRRjZJ4WbqWcdC1AsVsUNAePamHjLzgo lSZcG3ySCyKplbKFu2wMpLaRT0bbmOrbuP8NRheHMMy3FXHivATRaIIM02xEFPmfYo MqZIM3Wsdl0j2zhaghs9dfAHet66rW5dRsqCRJZw9fUEifPzWEmtd4UKW6EbL4p6+I GmXGm4+tle+Cg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 453A21804D0 for ; Tue, 17 Sep 2024 17:24:33 +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_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (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 17:24:30 +0000 (UTC) Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-20551e2f1f8so53235015ad.2 for ; Tue, 17 Sep 2024 10:22:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726593744; x=1727198544; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=D39HDpyCEgPXeYr6o8K8jhrJ4wCc4Q7kFVpYrg/BqtY=; b=ilr2ajXLSwnMdA/42VRDOXEOSSM80CRhO60EajLqEpq8AoEPLNarYVff3JuFYil2Gf Qeq3/AmTZQxh5tjJ4vC0CE1TBXgKSJ1oonEqIT3AFDrIxiRUL0Ix9ChO+fqlapghHlcl TGyZMcOtiijqZ24drjn0yoLEeswMrf6nk327f414CxBgxdtAS3A/VpWo0yD7ef7vIDkf wOYi2/D4WU98kbvC75cU6nq8416TqXMnGi5MGSQvCtUnX5JClsxjDVGgklXiWIzSYgOs 5icNeExhItcrVmlFTEHKFhY642iBCkCEY1dV62+F53/ChOUHs1ozhfuvtrTFlQXAWLoM fTlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726593744; x=1727198544; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=D39HDpyCEgPXeYr6o8K8jhrJ4wCc4Q7kFVpYrg/BqtY=; b=W4t9bRdDqNkVgBbl/lZh41RHWobY4HDLiDGCQj6KKdC32QH6whN3Jcqhc+TbzIwKIM MBqvTNssTNo2Llgh2Gfcs9GejTAb4HOrAoTsALJwpaW8N28QfSDoYtoCKn8HIetkLFwR QzLrRNq34uesJxp1pNcT0VdG504jLyBvbhweq9/F8U3kc504sgSIi1JSNlut3NzEw7IV nQmelwG9wB+5TpxA7Fn4A4HAXnkxbWqjncKp+llenqdoW7gkOZgC12kONp/sUd5/clch ZEX19gFgSqj+5zjDucWh/GRj5PRSuYpdakwtCJx2VBoKpCsIrLA5KVIwfy2jvAEubHhu 3GGg== X-Gm-Message-State: AOJu0YwlAT4k8c5xf8bibTBinWdJA5PqvyAfcfXp6p3t90LHPm85VFxG 5oILdB8vTU8tmI9bnb1qQCAjPupPegOq9cXM0/qG9oA5R+LWQMkgJNPlCt7P47NvnAAXydZM7+R lfSiFKmAFDNh/FnsLX9doMKyeFmgh7Q== X-Google-Smtp-Source: AGHT+IEmIZh5NsR9ltZhUHRXcubNodHhu2BOWAIHOY3cNuwb3LgrTCE6c5EmDjPho5lFj5IPPccuQnlIDjeEhJ75aps= X-Received: by 2002:a17:903:2352:b0:207:625:cef1 with SMTP id d9443c01a7336-20781b46ccdmr238201265ad.2.1726593744276; Tue, 17 Sep 2024 10:22:24 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <18603813-9ECB-4486-95EE-08BEDECAB88D@newclarity.net> In-Reply-To: Date: Tue, 17 Sep 2024 10:22:12 -0700 Message-ID: Subject: Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again) To: Mike Schinkel Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000cc976a062253eed3" From: jordan.ledoux@gmail.com (Jordan LeDoux) --000000000000cc976a062253eed3 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Sep 17, 2024 at 2:14=E2=80=AFAM Mike Schinkel = wrote: > > On Sep 17, 2024, at 1:37 AM, Jordan LeDoux > wrote: > > On Mon, Sep 16, 2024 at 9:35=E2=80=AFPM Mike Schinkel > wrote: > > > > Yes, if constraints of the nature I propose below are adopted. > > > > The biggest problem I have with operator overloads is that =E2=80=94 on= ce added > =E2=80=94 all code could potentially be "infected" with operator overload= s. > 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 eac= h > would be useful for different use-cases. As such I do not see these two a= s > 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 neede= d > 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 appli= es > 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 o= f > 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 wi= th > 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 the= y > explicitly allow it, especially as they may not have have tested code wit= h > 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 > > > > > > This is interesting, as I've never seen this in any language I > researched as part of operator overloading, and also was never given this > feedback or anything similar by anyone who provided feedback before. > > If all language features required prior art, there would never be > innovation in programming languages. So for anything that currently exist= s, > there was always a first language that implemented it. > > Of course when there is prior art we can use the heuristic of "All these > have done it before so it must be a good idea." But lack of prior art > should not be the reason to dismiss something, it should be evaluated on > its merits. > > > My initial reaction is that I do not understand how this is any better > than parameter typing. If you do not allow any objects into the scope you > are using operators, wouldn't that be the same as the kind of userland > control you are after? Or rather, how would it be substantially worse? > > How would a developer know if they are using an object that has operators= , > unless they study all the source code or at least the docs (assuming ther= e > are good docs, which there probably are not?) > > It might be illustrative to explicitly call out different scenarios I > envision in case some are not obvious. > > There are: > > 1. Internal projects that are almost entirely bespoke code, with an activ= e > team where the code is run by the code owners. Think a big company's > internal operations. > > 2. Agencies that build web projects using frameworks and libraries for > clients. > > 3. Smaller companies using frameworks and libraries for internal use, wit= h > a small team that may have many other duties, or those who outsource to > contractors when they need things, and breakage for them is can be very > painful. > > 4. Framework developers > > 5. Library developers > > 6. And probably a bunch of other scenarios, each slightly different. > > Each of those scenarios have a different level of knowledge about the cod= e > they work on. I'd expect #2 & #3 to have the least knowledge of the code > they use and would be most effected by other people's code doing things > they do not expect. > > I'd argue that #1 would have better knowledge of their code and would be > less affected by other people's code, except they probably have a huge > amount of bespoke code so one developer likely does not know what another > developer is doing, and especially if they have teams that developer tool= s > for other teams to use. > > Lastly #4 and #5 likely know their codebases the best, but they may creat= e > footguns for developers in category #2 and #3 if the language allows them > to. And vice-versa. > > So back to your question "If you do not allow any objects into the scope > you are using operators wouldn't that be the same as the kind of userland > control you are after?" So I ask =E2=80=94 How do I know if the objects I= am using > that were developed by others use operators or not? With free-reign > userland operator overloads we would be required to dig into the source f= or > the code written by others that we use to ensure I know if they have > operators and how they work. > > OTOH with my suggestion, we will know because the code will crash when no > opt-in is used. > > Note, I refer to cases where code that calls code evolves, uses dynamic > programming, and/or accepts mixed types. And I am especially talking abou= t > when developers create classes to wrap a built-in type and then implement > operators, but add special cases to them such as a String() class that > implements the concatenation operator but with a twist. > > > Your second example even includes a function that only accepts a > `ComplexNumber` object. I presume in your example there that if the > Attribute was removed, the function would just always produce a fatal > error, since that is the behavior of objects when used with `*`. > > Yes, that was the intention for the attribute, or lack of attribute in th= e > case you describe. > > > > > What it appears to me your proposal does is transform working operator > overloads into fatal errors if the user-code does not "opt-in". > > Correct. > > > But any such code would never actually survive long, wouldn't it? > > That is the feature, not a bug. > > > Without the opt-in, these objects would ALWAYS produce fatal errors > (which is what happens now), > > Well, we do not have operator overloads right now. With operator overload= s > they could run without crashing but have subtle bugs. > > Note I am not referring to highly specific functions written for highly > specific classes which is what I suspect you are envisioning. Based on yo= ur > past comments those seem to be the areas you operate in, i.e. math-relate= d. > > I am instead referring to code that is written to be generic but that end= s > up running code it did not intend to run because of edge cases that are > exposed by userland operators. > > > which would eventually show up in testing, QA, etc. > > Eventually. Assuming they have a good testing and QA process which many > PHP projects do not. PHP is a least-common denominator language because i= t > is one of the easiest to get started with. Many less experienced PHP > developers do not have good testing and QA processes. > > But even if they do have good testing and QA, the sooner the bugs appear > the less likely they will get deployed. > > > The developer would realize that they (presumably) were trying to do a > math operation on something they thought was only a numeric type, and the= n > guard against objects being passed into that context with control > statements, parameter types, etc. > > Exactly. In my proposed concept they would rework their expressions to > opt-in to using the overloaded operators once they ensure that they > understand how the code operates. > > > So it seems to me what this ACTUALLY guards against is developers who > inadvertently don't type-check their variables in code where the specific > type is relevant. > > OR do not fully know the details of the types they are using. > > OR they are using types that have been upgraded to now support operator > overloading, but they do not realize that. > > > After one round of testing, all of the code using operators would eithe= r > always allow objects and thus overloads, or never allow objects and thus > not use overloads. > > That assumes they crash. I am concerned for when they do not crash but > instead have subtle bugs. > > > There shouldn't even be any existing code that would be affected, since > any existing code would need to currently allow objects in a context wher= e > operators are used, which currently produces a fatal error 100% of the > time, (excepting internal classes which are mostly final anyway, and thus > unaffected by this proposal). > > It is correct that no old code can call other old code and use operators > on objects. > > But *new* code could call old code and then that old code could be made t= o > run operators without ever intending to be run in that manner. > > > What is the situation where your suggestion is implemented, a developer > does NOT opt-in to overloads, and they avoid unexpected behavior without > having to change their existing code to fix fatal errors? I don't see how > that is possible. > > In your hypothetical it appears you referred to only one developer. But > where I see issues is when there are two or more developers; a producer o= f > functions and a consumer of functions. > > Situation where there is free-reign userland operator overloading: Junio= r > developer Joe is using Symfony and learns about this great new operator > overload feature so decides to implement all the operators for all his > objects, and now he wants to start passing his objects to Symphony code. > Joe decides to be clever and implement "/" to concatenate paths strings > together but doesn't type his properties, and he ends up passing them to = a > Symfony function that uses `/` for division, and his program crashes with > very cryptic error messages. He reports them to the Symfony developers, > and it wastes a bunch of time for everyone until they finally figure out > why it failed, because nobody every considered a developer would do such = a > thing. > > Same scenario but with required opt-in. Joe does the same thing but this > time he gets a very clear message that says "Symfony Widget does not > support operator overloads." He googles and quickly finds out that what > that means and then goes to ask the Symfony team to support operator > overloads. They can choose to either add support, or not, but it is up to > them if they want to open the can of worms related to support that operat= or > overloading might cause. > > > Also, replying into a 3 year old reddit thread I linked to for referenc= e > is not what I intended, however I want to highlight one other thing you > commented there but not here for some reason: > > > > > To illustrate my point, imagine if we also allowed control structure > overloads. If we had them we could no longer read code and know that an > `if` is a branch and a `for` is a loop; either could be anything valid fo= r > any control structure. Talk about ambiguity! > > > > Indeed. I want to make sure that I have not been ambiguous after readin= g > this, because I found it somewhat troubling: > > > > I am looking at writing an RFC for specific *operators* that are finite > and defined within the RFC. I am not proposing something that would allow > control structures to be altered (I don't even think that would be possib= le > without essentially rewriting the entire Zend Engine specifically to do i= t). > > > > Operators are not control structures. Operators mutate the value or > state of a variable in a repeatable way, given the input states. There is > not even a generalized mechanism in my RFC for "arbitrary" overloads, and > the compiler was not implemented in a way that is generalized for it > either. It allows only exactly the operators that are part of the RFC, an= d > each are handled specifically and individually. > > I was ONLY using control structures as a more extreme analogy to operator > overloading to try to illustrate how =E2=80=94 the more things you make > configurable in a language =E2=80=94 the more you allow the ground to shi= ft beneath > a developer's feet, so to speak. > > An approach I use when trying to understand something that might be subtl= e > is to ask myself what a more extreme example is that would be analogous a= nd > then I consider that. > > So I was not saying you proposed that, I was equating control structure > overloading to operator overloading, but I explicitly meant control > structure overloading would be a more extreme opening up of PHP than > operator overloading. > > Clearly control structure overloading would be bad. I was trying to make > the point that operator overloading would cause problems for the same > reason, even if the problems would not be as extreme. > > I am sorry that my wording did not make it clear that I was using an > analogy, not referring to your RFC. > > Anyway, as a closing for this email, I know you badly want operator > overloading but there were enough people who disliked the idea to vote > against it last time so =E2=80=94 assuming my proposal could satisfy them= too =E2=80=94 it > seems like a great compromise to give you true operator overloading with > just a little extra boilerplate while at the same time allowing developer= s > to limit the scope of operator overloads to just those function where the= y > want to enable it. > > What's more, if after a few years we find out that my concerns really wer= e > for naught then a future RFC could open it up and remove the opt-in > requirement. > > But one thing is certain, if we open up operator overloading completely > one day one we could never go back to opt-in. > > -Mike While I do not presume to speak for all voters (I don't even have voting rights myself), my feeling from all of the conversations I have had over almost the last 4 years is that implementing your suggestion would virtually guarantee that the RFC is declined. You are suggesting providing a new syntax (which voters tend to be skeptical of) to create a situation where more errors occur (which voters tend to be skeptical of) to solve a problem which can be solved with existing syntax by simply type guarding your code to not allow any objects near your operators (which voters tend to be skeptical of) for which I cannot find any code examples that explain the problem it is solving (which voters tend to skeptical of). Jordan --000000000000cc976a062253eed3 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Tue, Sep 17, 2024 at 2:14=E2=80=AF= AM Mike Schinkel <mike@newclarity= .net> wrote:
> On Sep 17, 2024, at 1:37 AM, Jordan LeDoux <jordan.ledoux@gmail.com> w= rote:
> On Mon, Sep 16, 2024 at 9:35=E2=80=AFPM Mike Schinkel <mike@newclarity.net> wr= ote:
>
> Yes, if constraints of the nature I propose below are adopted.
>
> The biggest problem I have with operator overloads is that =E2=80=94 o= nce 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 opini= on and I would begin to support them.=C2=A0
>
> What might opt-in look like?=C2=A0 I propose two (2) mechanisms of whi= ch 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 s= upport userland operator overloading. This would allow a developer to isola= te 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 ]};=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0// Uses operator operloading sigils
> echo $cnum3->realPart.' + '.$cnum3->imaginaryPart.'i= ';
>
> 2. For when using `{[...]}` would be annoying because it would be need= ed 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 c= an 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 userla= nd 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 drop= ped 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 {
>=C2=A0 =C2=A0$cnum3 =3D $cnum1 * $cnum2;
>=C2=A0 =C2=A0return sprintf("%d + %di", $cnum3->realPart, = $cnum3->imaginaryPart);
> }
>
> If this approach were included in the RFC then it would also ensure th= ere 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 newe= r instances incorporating operator overloads are passed to functions that d= id not have parameters type hinted but were not intend to be used with oper= ator overloads resulting in subtle potential breakage.
>
> This argument is also consistent with the argument people had about no= t allowing default values to be generically used in calls to the function f= unction. 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 overlo= ads should not be used with=C2=A0 userland operator overloads unless they e= xplicitly allow it, especially as they may not have have tested code with o= perator overloads.
>
> Anyway, that is my two cents worth.
>
> TL;DR?=C2=A0 I argue that PHP should operator overloads but ONLY if th= ere is a mechanism that requires the user of expressions that call overload= ed operators to explicitly opt-in to their use.
>
> -Mike
>
>
> This is interesting, as I've never seen this in any language I res= earched as part of operator overloading, and also was never given this feed= back or anything similar by anyone who provided feedback before.

If all language features required prior art, there would never be innovatio= n in programming languages. So for anything that currently exists, there wa= s always a first language that implemented it.

Of course when there is prior art we can use the heuristic of "All the= se have done it before so it must be a good idea."=C2=A0 But lack of p= rior art should not be the reason to dismiss something, it should be evalua= ted on its merits.

> My initial reaction is that I do not understand how this is any better= than parameter typing. If you do not allow any objects into the scope you = are using operators, wouldn't that be the same as the kind of userland = control you are after? Or rather, how would it be substantially worse?

How would a developer know if they are using an object that has operators, = unless they study all the source code or at least the docs (assuming there = are good docs, which there probably are not?)

It might be illustrative to explicitly call out different scenarios I envis= ion in case some are not obvious.=C2=A0

There are:

1. Internal projects that are almost entirely bespoke code, with an active = team where the code is run by the code owners. Think a big company's in= ternal operations.

2. Agencies that build web projects using frameworks and libraries for clie= nts.

3. Smaller companies using frameworks and libraries for internal use, with = a small team that may have many other duties, or those who outsource to con= tractors when they need things, and breakage for them is can be very painfu= l.

4. Framework developers

5. Library developers

6. And probably a bunch of other scenarios, each slightly different.

Each of those scenarios have a different level of knowledge about the code = they work on. I'd expect #2 & #3 to have the least knowledge of the= code they use and would be most effected by other people's code doing = things they do not expect.

I'd argue that #1 would have better knowledge of their code and would b= e less affected by other people's code, except they probably have a hug= e amount of bespoke code so one developer likely does not know what another= developer is doing, and especially if they have teams that developer tools= for other teams to use.

Lastly #4 and #5 likely know their codebases the best, but they may create = footguns for developers in category #2 and #3 if the language allows them t= o. And vice-versa.

So back to your question "If you do not allow any objects into the sco= pe you are using operators wouldn't that be the same as the kind of use= rland control you are after?" So I ask =E2=80=94 How do I know if the = objects I am using that were developed by others use operators or not? With= free-reign userland operator overloads we would be required to dig into th= e source for the code written by others that we use to ensure I know if the= y have operators and how they work.

OTOH with my suggestion, we will know because the code will crash when no o= pt-in is used.

Note, I refer to cases where code that calls code evolves, uses dynamic pro= gramming, and/or accepts mixed types. And I am especially talking about whe= n developers create classes to wrap a built-in type and then implement oper= ators, but add special cases to them such as a String() class that implemen= ts the concatenation operator but with a twist.

> Your second example even includes a function that only accepts a `Comp= lexNumber` object. I presume in your example there that if the Attribute wa= s removed, the function would just always produce a fatal error, since that= is the behavior of objects when used with `*`.

Yes, that was the intention for the attribute, or lack of attribute in the = case you describe.

>
> What it appears to me your proposal does is transform working operator= overloads into fatal errors if the user-code does not "opt-in".<= br>
Correct.

> But any such code would never actually survive long, wouldn't it?<= br>
That is the feature, not a bug.

> Without the opt-in, these objects would ALWAYS produce fatal errors (w= hich is what happens now),

Well, we do not have operator overloads right now. With operator overloads = they could run without crashing but have subtle bugs.=C2=A0

Note I am not referring to highly specific functions written for highly spe= cific classes which is what I suspect you are envisioning. Based on your pa= st comments those seem to be the areas you operate in, i.e. math-related. <= br>
I am instead referring to code that is written to be generic but that ends = up running code it did not intend to run because of edge cases that are exp= osed by userland operators.

> which would eventually show up in testing, QA, etc.

Eventually.=C2=A0 Assuming they have a good testing and QA process which ma= ny PHP projects do not. PHP is a least-common denominator language because = it is one of the easiest to get started with. Many less experienced PHP dev= elopers do not have good testing and QA processes.

But even if they do have good testing and QA, the sooner the bugs appear th= e less likely they will get deployed.

> The developer would realize that they (presumably) were trying to do a= math operation on something they thought was only a numeric type, and then= guard against objects being passed into that context with control statemen= ts, parameter types, etc.

Exactly. In my proposed concept they would rework their expressions to opt-= in to using the overloaded operators once they ensure that they understand = how the code operates.

> So it seems to me what this ACTUALLY guards against is developers who = inadvertently don't type-check their variables in code where the specif= ic type is relevant.

OR do not fully know the details of the types they are using.

OR they are using types that have been upgraded to now support operator ove= rloading, but they do not realize that.

> After one round of testing, all of the code using operators would eith= er always allow objects and thus overloads, or never allow objects and thus= not use overloads.

That assumes they crash. I am concerned for when they do not crash but inst= ead have subtle bugs.

> There shouldn't even be any existing code that would be affected, = since any existing code would need to currently allow objects in a context = where operators are used, which currently produces a fatal error 100% of th= e time, (excepting internal classes which are mostly final anyway, and thus= unaffected by this proposal).

It is correct that no old code can call other old code and use operators on= objects.

But *new* code could call old code and then that old code could be made to = run operators without ever intending to be run in that manner.

> What is the situation where your suggestion is implemented, a develope= r does NOT opt-in to overloads, and they avoid unexpected behavior without = having to change their existing code to fix fatal errors? I don't see h= ow that is possible.

In your hypothetical it appears you referred to only one developer. But whe= re I see issues is when there are two or more developers; a producer of fun= ctions and a consumer of functions.

Situation where there is free-reign userland operator overloading:=C2=A0 Ju= nior developer Joe is using Symfony and learns about this great new operato= r overload feature so decides to implement all the operators for all his ob= jects, and now he wants to start passing his objects to Symphony code. Joe = decides to be clever and implement "/" to concatenate paths strin= gs together but doesn't type his properties, and he ends up passing the= m to a Symfony function that uses `/` for division, and his program crashes= with very cryptic error messages.=C2=A0 He reports them to the Symfony dev= elopers, and it wastes a bunch of time for everyone until they finally figu= re out why it failed, because nobody every considered a developer would do = such a thing.

Same scenario but with required opt-in. Joe does the same thing but this ti= me he gets a very clear message that says "Symfony Widget does not sup= port operator overloads."=C2=A0 He googles and quickly finds out that = what that means and then goes to ask the Symfony team to support operator o= verloads. They can choose to either add support, or not, but it is up to th= em if they want to open the can of worms related to support that operator o= verloading might cause.

> Also, replying into a 3 year old reddit thread I linked to for referen= ce is not what I intended, however I want to highlight one other thing you = commented there but not here for some reason:
>
> > To illustrate my point, imagine if we also allowed control struct= ure overloads. If we had them we could no longer read code and know that an= `if` is a branch and a `for` is a loop; either could be anything valid for= any control structure. Talk about ambiguity!
>
> Indeed. I want to make sure that I have not been ambiguous after readi= ng this, because I found it somewhat troubling:
>
> I am looking at writing an RFC for specific *operators* that are finit= e and defined within the RFC. I am not proposing something that would allow= control structures to be altered (I don't even think that would be pos= sible without essentially rewriting the entire Zend Engine specifically to = do it).
>
> Operators are not control structures. Operators mutate the value or st= ate of a variable in a repeatable way, given the input states. There is not= even a generalized mechanism in my RFC for "arbitrary" overloads= , and the compiler was not implemented in a way that is generalized for it = either. It allows only exactly the operators that are part of the RFC, and = each are handled specifically and individually.

I was ONLY using control structures as a more extreme analogy to operator o= verloading to try to illustrate how =E2=80=94 the more things you make conf= igurable in a language =E2=80=94 the more you allow the ground to shift ben= eath a developer's feet, so to speak.

An approach I use when trying to understand something that might be subtle = is to ask myself what a more extreme example is that would be analogous and= then I consider that.=C2=A0

So I was not saying you proposed that, I was equating control structure ove= rloading to operator overloading, but I explicitly meant control structure = overloading would be a more extreme opening up of PHP than operator overloa= ding.=C2=A0

Clearly control structure overloading would be bad. I was trying to make th= e point that operator overloading would cause problems for the same reason,= even if the problems would not be as extreme.

I am sorry that my wording did not make it clear that I was using an analog= y, not referring to your RFC.

Anyway, as a closing for this email, I know you badly want operator overloa= ding but there were enough people who disliked the idea to vote against it = last time so =E2=80=94 assuming my proposal could satisfy them too =E2=80= =94 it seems like a great compromise to give you true operator overloading = with just a little extra boilerplate while at the same time allowing develo= pers to limit the scope of operator overloads to just those function where = they want to enable it.

What's more, if after a few years we find out that my concerns really w= ere for naught then a future RFC could open it up and remove the opt-in req= uirement.

But one thing is certain, if we open up operator overloading completely one= day one we could never go back to opt-in.

-Mike

While I do not presume to speak for a= ll voters (I don't even have voting rights myself), my feeling from all= of the conversations I have had over almost the last 4 years is that imple= menting your suggestion would virtually guarantee that the RFC is declined.= You are suggesting providing a new syntax (which voters tend to be skeptic= al of) to create a situation where more errors occur (which voters tend to = be skeptical of) to solve a problem which can be solved with existing synta= x by simply type guarding your code to not allow any objects near your oper= ators (which voters tend to be skeptical of) for which I cannot find any co= de examples that explain the problem it is solving (which voters tend to sk= eptical of).

Jordan
--000000000000cc976a062253eed3--